v0.27.2 — Persiste channel + canSeeBetas dans le cache license

Bug : le LicenseValidationResponse réhydraté par GetCached() ne contenait
plus les champs Channel et CanSeeBetas (introduits en v0.26.0). Cause :
LocalConfig.LicenseConfig ne persistait pas ces deux champs, donc à chaque
relance du launcher (ou simple GetCached), Channel retombait à null et
CanSeeBetas à false.

Conséquence visible : un client avec license channel='firefighter'
côté serveur fetchait toujours /api/manifest (sans ?channel=), recevait
le manifest default-only, et ne voyait jamais le build firefighter même
après re-validation de license.

Fix :
- Ajout des champs CachedChannel + CachedCanSeeBetas sur LicenseConfig
  (persistés dans %LocalAppData%\PSLauncher\config.json)
- SaveCached() écrit ces champs depuis la réponse signée du serveur
- GetCached() les restaure dans la LicenseValidationResponse renvoyée

Migration silencieuse : un launcher pre-v0.27.2 a CachedChannel=null
et CachedCanSeeBetas=false dans son config.json. Au prochain Vérifier
les MAJ, RefreshLicenseFromServerAsync re-valide la license, le serveur
renvoie les valeurs courantes, SaveCached les persiste. La fois d'après
le launcher fetch correctement avec ?channel=X.

À tester chez l'utilisateur :
1. Recompiler + réinstaller le launcher en v0.27.2
2. Settings → Vérifier les MAJ (force la revalidation license)
3. Vérifier %LocalAppData%\PSLauncher\config.json :
   "CachedChannel": "firefighter" doit apparaître
4. Le manifest-cache.json devrait alors contenir le bon ZIP

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-05 09:37:19 +02:00
parent 67678fe173
commit d9c3f09e9a
4 changed files with 29 additions and 4 deletions

View File

@@ -11,7 +11,7 @@
#define MyAppName "PROSERVE Launcher"
#define MyAppShortName "PS_Launcher"
#define MyAppVersion "0.27.1"
#define MyAppVersion "0.27.2"
#define MyAppPublisher "ASTERION VR"
#define MyAppURL "https://asterionvr.com"
#define MyAppExeName "PS_Launcher.exe"

View File

@@ -18,9 +18,9 @@
<Product>PROSERVE Launcher</Product>
<Copyright>© 2026 ASTERION VR — All rights reserved</Copyright>
<RootNamespace>PSLauncher.App</RootNamespace>
<Version>0.27.1</Version>
<AssemblyVersion>0.27.1.0</AssemblyVersion>
<FileVersion>0.27.1.0</FileVersion>
<Version>0.27.2</Version>
<AssemblyVersion>0.27.2.0</AssemblyVersion>
<FileVersion>0.27.2.0</FileVersion>
<!-- Single-file self-contained publish profile (used by `dotnet publish`) -->
<PublishSingleFile>true</PublishSingleFile>

View File

@@ -212,6 +212,13 @@ public sealed class LicenseService : ILicenseService
OwnerName = _config.License.CachedOwnerName,
DownloadEntitlementUntil = _config.License.CachedEntitlementUntil,
ServerTime = lastValidation,
// Restauration des champs channel + canSeeBetas (ajoutés persistants
// depuis v0.27.2). Sans ça, le channelProvider du ManifestService
// retombait sur null à chaque relance, le client fetch sans
// ?channel=, et l'utilisateur ne voyait que les versions default —
// jamais les builds spécifiques à son channel (firefighter, police…).
Channel = _config.License.CachedChannel,
CanSeeBetas = _config.License.CachedCanSeeBetas,
};
}
@@ -227,6 +234,8 @@ public sealed class LicenseService : ILicenseService
_config.License.CachedOwnerName = response.OwnerName;
_config.License.CachedEntitlementUntil = response.DownloadEntitlementUntil;
_config.License.CachedStatus = response.Status;
_config.License.CachedChannel = response.Channel;
_config.License.CachedCanSeeBetas = response.CanSeeBetas;
_configStore.Save(_config);
}

View File

@@ -322,6 +322,22 @@ public sealed class LicenseConfig
public DateTime? CachedEntitlementUntil { get; set; }
public string? CachedOwnerName { get; set; }
/// <summary>
/// Channel de distribution attribué à cette license côté serveur (NULL =
/// aucun ⇒ accès uniquement aux versions taggées 'default'). Persisté ici
/// pour que <see cref="ILicenseService.GetCached"/> restaure ce champ entre
/// deux lancements du launcher — sans ça, le channelProvider du
/// ManifestService retombait sur null à chaque relance et le client
/// fetchait toujours le manifest default.
/// </summary>
public string? CachedChannel { get; set; }
/// <summary>
/// Flag <c>canSeeBetas</c> de la license. Persisté pour la même raison
/// que <see cref="CachedChannel"/> : restauration entre deux lancements.
/// </summary>
public bool CachedCanSeeBetas { get; set; }
/// <summary>
/// Statut tel que renvoyé par le serveur lors de la dernière validation : "valid",
/// "expired", "revoked", "invalid", "machine_limit_exceeded". Persisté pour qu'une