v1.0.11 — /manifest : opt-in multiChannel pour ne plus dédupliquer par version
Bug rapporté après v1.0.10 : client sur license channel=full avec les deux entries v1.5.4.32 dans le backoffice (Entry #1 tagged firefighter+full, Entry #2 tagged full), le launcher n'affichait toujours qu'une seule ligne. Root cause côté serveur, PAS côté client cette fois. Manifest.php faisait un « group by version + pick most specific » dans filterVersions() — comportement historique introduit pour ne pas faire crasher les vieux clients qui déduisaient par ToDictionary(v.Version). Résultat : Entry #2 était filtrée avant même d'atteindre le launcher. Ce filtrage était nécessaire à l'époque (vieux clients) mais bloque tous les fixes multi-channels client (v1.0.8-1.0.10) qui avaient rendu le client capable d'afficher plusieurs entries au même numéro. Fix : opt-in via query param sur /manifest?multiChannel=1 Server (Manifest.php) : • filterVersions() prend un `bool $multiChannel = false`. • Si true → skip group-by, retourne toutes les entries visibles. • Si false (défaut, vieux clients) → comportement historique préservé. • Query param `multiChannel` lu depuis $_GET, transmis à filterVersions. Client (ManifestService.FetchFromOvhAsync) : • Ajoute `?multiChannel=1` inconditionnellement. Un serveur ancien ignore silencieusement le param (pas de header d'échec). • Combiné avec &channel=X quand la license a un channel. Rétro-compat : • Vieux client (v1.0.9-) + serveur nouveau : n'envoie pas multiChannel=1, serveur dédupe comme avant, launcher ne crash pas. • Client nouveau (v1.0.11+) + serveur ancien : le param est ignoré, même comportement qu'avant (dédup côté serveur, une seule row visible). • Client nouveau + serveur nouveau (config voulue) : les deux entries remontent, le row-key-par-Id de v1.0.10 fait le reste. Bump : 1.0.10 → 1.0.11 (fix ciblé serveur+client). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,9 +18,9 @@
|
||||
<Product>PROSERVE Launcher</Product>
|
||||
<Copyright>© 2026 ASTERION VR — All rights reserved</Copyright>
|
||||
<RootNamespace>PSLauncher.App</RootNamespace>
|
||||
<Version>1.0.10</Version>
|
||||
<AssemblyVersion>1.0.10.0</AssemblyVersion>
|
||||
<FileVersion>1.0.10.0</FileVersion>
|
||||
<Version>1.0.11</Version>
|
||||
<AssemblyVersion>1.0.11.0</AssemblyVersion>
|
||||
<FileVersion>1.0.11.0</FileVersion>
|
||||
|
||||
<!-- Single-file self-contained publish profile (used by `dotnet publish`) -->
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
|
||||
@@ -146,9 +146,16 @@ public sealed class ManifestService : IManifestService
|
||||
// Whitelist côté client aussi pour éviter des chars exotiques qui casseraient l'URL.
|
||||
var channel = _channelProvider();
|
||||
var baseUrl = TrimSlash(_serverBaseUrlProvider()) + "/manifest";
|
||||
var url = !string.IsNullOrWhiteSpace(channel) && System.Text.RegularExpressions.Regex.IsMatch(channel!, "^[a-z0-9_-]{1,64}$")
|
||||
? $"{baseUrl}?channel={Uri.EscapeDataString(channel!)}"
|
||||
: baseUrl;
|
||||
// Query params : ?channel=X (filtrage par channel license) + &multiChannel=1
|
||||
// (opt-in au comportement v1.0.10+ : le serveur envoie plusieurs entries au
|
||||
// même numéro de version sans dédup, le client sait afficher chacune sur
|
||||
// sa row). Toujours envoyé — les serveurs anciens l'ignorent silencieusement.
|
||||
var qs = new System.Text.StringBuilder("?multiChannel=1");
|
||||
if (!string.IsNullOrWhiteSpace(channel) && System.Text.RegularExpressions.Regex.IsMatch(channel!, "^[a-z0-9_-]{1,64}$"))
|
||||
{
|
||||
qs.Append("&channel=").Append(Uri.EscapeDataString(channel!));
|
||||
}
|
||||
var url = baseUrl + qs.ToString();
|
||||
using var ovhCts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||
ovhCts.CancelAfter(OvhFetchTimeoutMs);
|
||||
using var req = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
|
||||
Reference in New Issue
Block a user