• v3.0.0 ade18e84d2

    nicolas released this 2026-11-09 15:09:38 +01:00 | 72 commits to master since this release

    🖥️ Launcher 3.0.0 — Bouton « Aide » et demandes des joueurs

    Première fonction tournée vers les joueurs depuis le menu d'administration : un bouton Aide permet d'envoyer, sans compte, un avis, une demande d'évolution, un bug ou autre chose, pour le jeu sélectionné. Chaque type a ses propres champs (note en étoiles, gravité, étapes pour reproduire…), et le joueur reçoit une référence à citer.

    Côté administration, une nouvelle page « Demandes des joueurs » range les demandes par jeu, avec statut et note interne. Les demandes sont anonymes : aucun compte, aucune adresse IP enregistrée. Le journal d'audit est désormais purgé automatiquement au-delà de 12 mois. Serveur à redéployer et à configurer avant de publier cette version (voir Mise à niveau).

    ✨ En bref

    Changement
    🆕 Nouveau Bouton Aide dans la barre de titre : avis, demande d'évolution, bug ou autre, pour le jeu sélectionné
    🆕 Nouveau Formulaires à champs prédéfinis selon le type, contrôlés avant l'envoi ; référence FB-XXXX-XXXX remise au joueur
    🆕 Nouveau Page d'administration « Demandes des joueurs » : choix du jeu, filtres, fiche, statut, note interne, suppression
    🆕 Nouveau Carte « Demandes des joueurs » sur le tableau de bord (nouvelles demandes par jeu)
    🆕 Nouveau Purge automatique : demandes (12 mois après clôture, 24 mois au plus) et journal d'audit (12 mois)
    🛡️ Sécurité Première route d'envoi ouverte à tous : défi anti-spam, limites par adresse, plafonds, contrôle complet du contenu
    🛡️ Vie privée Demandes anonymes : ni compte, ni adresse IP, ni identifiant du PC ; informations techniques facultatives et affichées avant l'envoi
    🖧 Serveur Nouveau module Feedback, nouvelles permissions : à redéployer et à configurer (voir Mise à niveau)
    🧪 Qualité 30 nouveaux tests automatisés (312 au total)

    💬 Bouton « Aide » (joueurs)

    Le bouton (bulle avec un point d'interrogation) se trouve dans la barre de titre, à gauche du bouton « Site officiel ». Il est le même pour tous les jeux : la demande est rattachée au jeu sélectionné dans la liste de gauche au moment de l'ouverture, affiché en en-tête (« Demande pour : … ») et non modifiable pendant la saisie.

    Étape Contenu
    1. Type Quatre tuiles : Avis, Demande d'évolution, Bug, Autre
    2. Formulaire Titre + champs prédéfinis du type ; compteur de caractères ; erreurs signalées sous chaque champ
    3. Envoyée Message de remerciement et référence FB-XXXX-XXXX (bouton « Copier »)

    Champs prédéfinis (* obligatoire)

    Type Champs
    ⭐ Avis Note de 1 à 5 étoiles* ; sujet* (le jeu dans son ensemble, gameplay, graphismes, son et musique, performances, histoire et ambiance, launcher, autre) ; ce que vous aimez ; ce qui pourrait être amélioré ; recommanderiez-vous le jeu ? (oui / peut-être / non)
    💡 Demande d'évolution Domaine* (gameplay, contenu, interface et menus, accessibilité, launcher, autre) ; description de l'idée* ; quel problème cela résoudrait-il ? ; importance (un petit plus / utile / importante)
    🐞 Bug Catégorie* (plantage, graphismes, son, gameplay, performances, installation ou mise à jour, launcher, autre) ; gravité* (mineur / gênant / bloquant / plantage) ; fréquence* (à chaque fois / souvent / parfois / une seule fois) ; étapes pour reproduire* ; résultat attendu ; résultat obtenu*
    💬 Autre Message*
    • Informations techniques (case à cocher) : version du launcher, version du jeu installée, version de Windows, langue. Le contenu exact est affiché avant l'envoi. La case est cochée par défaut pour un bug seulement.
    • Contrôle avant l'envoi, avec les mêmes règles que le serveur : titre de 5 à 120 caractères, textes de 2 000 caractères et 40 lignes au plus, 8 000 caractères au total.
    • Saisie conservée en cas d'échec (pas de réseau, serveur occupé…) : il suffit de cliquer de nouveau sur « Envoyer ». « Changer de type » garde aussi la saisie du type en cours.
    • Échap ne ferme pas la fenêtre pendant la saisie (pas de texte perdu par mégarde).
    • Le launcher ne contacte le serveur qu'au moment de l'envoi, jamais en arrière-plan.
    • Pas de réponse possible : la demande est anonyme. Un futur module « comptes joueurs » permettra d'échanger avec l'équipe sur les nouvelles demandes ; celles envoyées d'ici là resteront anonymes.
    • Bouton absent si le launcher n'a pas d'adresse d'API (apiUrl de launcher.json).

    🗂️ Page « Demandes des joueurs » (administration)

    Élément Comportement
    Choix du jeu Une tuile par jeu, avec « N nouvelles · N à traiter · N au total » ; un seul jeu : choisi d'office. Les demandes d'un jeu ne se mélangent jamais à celles d'un autre
    Filtres Type ; statut (« À traiter » par défaut, nouvelles, en cours, closes, traitées, rejetées, doublons, toutes) ; recherche dans le titre ou la référence
    Liste Les plus récentes d'abord, 100 par page (« Charger plus ») ; point orange = nouvelle ; note (avis) ou gravité (bug) en aperçu
    Fiche Tous les champs avec leurs libellés, en texte brut (sélectionnable, jamais interprété) ; informations techniques ; référence copiable
    Traitement Statut Nouvelle → En cours → Traitée / Rejetée / Doublon ; note interne (500 caractères, visible des seuls administrateurs) ; suppression définitive après confirmation
    Bandeaux Réception désactivée sur le serveur ; plafond atteint ; demande modifiée par un autre administrateur (rien n'est écrasé, « Recharger »)
    Tableau de bord Carte « Demandes des joueurs » : nouvelles demandes par jeu, icône orange s'il y en a

    Permissions

    Permission Propriétaire Administrateur Éditeur Usage
    feedback.read ✔ ✔ Lire les demandes (chaque consultation est inscrite au journal)
    feedback.manage ✔ ✔ Statut, note interne, suppression

    ⚠️ Serveur déjà installé : le groupe Propriétaire reçoit ces permissions d'office, mais pas les autres groupes existants. Aucun droit n'est ajouté sans l'action d'un propriétaire : page « Groupes et permissions » › « Administrateur » › cocher les deux permissions. L'Éditeur n'y a pas accès par défaut, car le texte libre peut contenir des données personnelles.


    🗑️ Conservation et purge automatique

    Le serveur applique ces durées au démarrage puis toutes les 24 heures :

    Données Durée Réglage Journal
    Demande close (traitée, rejetée, doublon) 12 mois après la clôture Feedback:RetentionClosedMonths feedback.purge
    Toute demande 24 mois après réception Feedback:RetentionMaxMonths feedback.purge
    Journal d'audit (audit-AAAA-MM.jsonl) 12 mois Audit:RetentionMonths (1 à 120) audit.purge
    • Cette purge corrige l'écart RGPD relevé sur le journal d'audit, qui était conservé sans limite. La CNIL recommande 6 mois à 1 an pour les journaux de sécurité.
    • Un fichier mensuel d'audit est supprimé quand tous ses jours dépassent la durée : le mois le plus ancien conservé peut donc compter quelques semaines de plus.

    🛡️ Sécurité

    C'est la première route d'écriture ouverte à tous. Elle est désactivée par défaut, et le serveur reste seul juge : un launcher modifié ou un script ne contourne rien.

    Menace Défense
    Spam, robots Défi anti-spam (calcul SHA-256, une fraction de seconde pour le joueur) sans état, à usage unique, valable 10 min ; aucun service tiers, aucun captcha
    Envois en rafale 3 demandes par 10 min et 10 par jour par adresse IP (IPv6 : par /64), comptées en mémoire seulement ; limite de débit ASP.NET (10/min) et nginx (6/min) ; 429 avec délai
    Disque rempli Corps de 16 Ko ; 300 demandes par jour et par jeu, 5 000 par jeu, 100 Mo au total, 500 Mo d'espace libre minimum ; au-delà, refus limité à ce module (503)
    Requête forgée Contrôle complet par le serveur, avec les mêmes règles que le launcher ; identifiant, référence, date et statut posés par le serveur
    Texte piégé Caractères de contrôle, invisibles, de mise en forme, d'inversion du sens d'écriture, d'usage privé et demi-caractères refusés ; affichage en texte brut dans le menu
    Chemin forgé Jeu accepté seulement s'il est configuré ; seul l'identifiant de la configuration sert à construire un chemin (. et .. refusés)
    Lecture non autorisée Permissions revérifiées à chaque requête ; consultations inscrites au journal (feedback.view), sans le contenu
    Jeton de session volé Statut, note et suppression en requêtes signées par la clé de l'administrateur

    🔒 Vie privée

    • Aucune adresse IP n'est enregistrée avec une demande, ni dans l'audit de son envoi (feedback.submit : référence, jeu, type).
    • nginx n'écrit pas les deux routes des joueurs dans ses journaux (access_log off) : l'heure d'envoi ne peut pas être rapprochée d'une adresse.
    • Aucun identifiant du PC n'est envoyé : ni nom du PC, ni nom d'utilisateur, ni chemin, ni matériel. Agent utilisateur générique GameLauncher/<version>.
    • Stockage dans les données privées du serveur (/var/lib/launcher-api/feedback, droits 0700/0600), jamais servi par nginx.

    🗄️ Choix du stockage

    Un fichier JSON par demande, rangé par jeu et par mois, écrit de façon atomique. Un index est gardé en mémoire.

    SQLite a été évalué et écarté pour ce module, pour trois raisons :

    • les volumes sont plafonnés et il n'y a aucune relation entre les données ;
    • une demande se modifie seule, et la purge revient à supprimer des fichiers ;
    • SQLite ajouterait une bibliothèque native à maintenir sur le VPS, sans gain de sécurité.

    Il sera réévalué pour le futur module « comptes + échanges » (docs/ADMIN-ARCHITECTURE.md, § 11 quinquies).


    🧪 Tests

    Fichier Tests
    Contracts/FeedbackRulesTests.cs (nouveau) 12 : formulaires cohérents, texte normalisé, caractères invisibles ou spéciaux refusés, bornes, preuve anti-spam, références, validation complète
    Server/FeedbackModuleTests.cs (nouveau) 14 : réception désactivée par défaut, demande anonyme enregistrée sans adresse IP, défi obligatoire et à usage unique, jeux acceptés (.., ., inconnu), contenu refusé, limites par adresse, plafond, statut et note signés et journalisés, Éditeur sans accès, pages et filtres, purge des demandes et du journal d'audit
    Admin/FeedbackPanelTests.cs (nouveau) 4 : formulaire du joueur (contrôle local, envoi, référence ; saisie conservée en cas d'échec ; étoiles et choix facultatifs), page d'administration de bout en bout (tableau de bord, choix du jeu, fiche, traitement, filtres, suppression)

    312 tests au vert.

    📂 Fichiers modifiés

    Contrats

    • src/GameLauncher.Contracts/Feedback/FeedbackForms.cs (nouveau)
    • src/GameLauncher.Contracts/Feedback/FeedbackRules.cs (nouveau)
    • src/GameLauncher.Contracts/Feedback/FeedbackProof.cs (nouveau)
    • src/GameLauncher.Contracts/Feedback/FeedbackDtos.cs (nouveau)
    • src/GameLauncher.Contracts/ApiRoutes.cs
    • src/GameLauncher.Contracts/Dtos/SystemDtos.cs
    • src/GameLauncher.Contracts/Security/AdminPermissions.cs
    • src/GameLauncher.Contracts/Security/AdminRoles.cs
    • src/GameLauncher.Contracts/Security/AdminGroups.cs

    Client de l'API

    • src/GameLauncher.ApiClient/LauncherApiClient.cs
    • src/GameLauncher.ApiClient/AdminSession.cs

    Serveur

    • server/GameLauncher.Server/Modules/Feedback/FeedbackModule.cs (nouveau)
    • server/GameLauncher.Server/Security/FeedbackGuard.cs (nouveau)
    • server/GameLauncher.Server/Storage/FeedbackStore.cs (nouveau)
    • server/GameLauncher.Server/Hosting/RetentionService.cs (nouveau)
    • server/GameLauncher.Server/Hosting/LauncherApiOptions.cs
    • server/GameLauncher.Server/Hosting/ServerApp.cs
    • server/GameLauncher.Server/Hosting/IApiModule.cs
    • server/GameLauncher.Server/Storage/AuditLog.cs
    • server/GameLauncher.Server/appsettings.json

    Déploiement

    • server/deploy/nginx-api.conf
    • server/deploy/LISEZMOI.md

    Module « Aide » (nouveau projet)

    • src/GameLauncher.Modules.Feedback/GameLauncher.Modules.Feedback.csproj (nouveau)
    • src/GameLauncher.Modules.Feedback/FeedbackFormViewModel.cs (nouveau)
    • src/GameLauncher.Modules.Feedback/FeedbackFieldViewModel.cs (nouveau)
    • src/GameLauncher.Modules.Feedback/FeedbackTech.cs (nouveau)
    • GameLauncher.sln

    Menu d'administration

    • src/GameLauncher.Modules.Admin/Feedback/FeedbackAdminModule.cs (nouveau)
    • src/GameLauncher.Modules.Admin/Feedback/FeedbackPanelViewModel.cs (nouveau)
    • src/GameLauncher.Modules.Admin/Feedback/FeedbackItems.cs (nouveau)
    • src/GameLauncher.Modules.Admin/ViewModels/DashboardPanelViewModel.cs

    Launcher (WPF)

    • src/GameLauncher/Views/FeedbackWindow.xaml (nouveau)
    • src/GameLauncher/Views/FeedbackWindow.xaml.cs (nouveau)
    • src/GameLauncher/Services/FeedbackWindowService.cs (nouveau)
    • src/GameLauncher/Views/MainWindow.xaml
    • src/GameLauncher/Views/MainWindow.xaml.cs
    • src/GameLauncher/ViewModels/LauncherViewModel.cs
    • src/GameLauncher/Themes/Icons.xaml
    • src/GameLauncher/Themes/Admin.xaml
    • src/GameLauncher/App.xaml.cs
    • src/GameLauncher/GameLauncher.csproj (version 3.0.0, référence au module « Aide »)

    Tests

    • tests/GameLauncher.Tests/Contracts/FeedbackRulesTests.cs (nouveau)
    • tests/GameLauncher.Tests/Server/FeedbackModuleTests.cs (nouveau)
    • tests/GameLauncher.Tests/Admin/FeedbackPanelTests.cs (nouveau)
    • tests/GameLauncher.Tests/GameLauncher.Tests.csproj

    Documentation et notes

    • README.md
    • docs/ADMIN-ARCHITECTURE.md
    • tools/notes-launcher.txt

    ⬆️ Mise à niveau

    Ordre conseillé : serveur d'abord, launcher ensuite. Un launcher 3.0.0 relié à un serveur pas encore à jour, ou dont la réception n'est pas activée, affiche le bouton « Aide » ; l'envoi répond alors « L'envoi des demandes n'est pas disponible pour le moment ».

    • Serveur (Launcher API) : à redéployer et à configurer (server/deploy/LISEZMOI.md, étape 8, puis étape 3 octies) :
      1. appsettings.Production.json › section LauncherApi : "Feedback": { "Enabled": true, "Games": [ "EZR" ] } (réception désactivée par défaut) ;
      2. nginx : zone limit_req_zone $binary_remote_addr zone=feedback_par_ip:10m rate=6r/m; dans /etc/nginx/conf.d/securite.conf, puis les deux blocs location = /api/v1/feedback… de server/deploy/nginx-api.conf ; sudo nginx -t && sudo systemctl reload nginx ;
      3. sudo systemctl restart launcher-api (les sessions ouvertes sont fermées : reconnexion).
      • La purge du journal d'audit s'applique dès le premier démarrage : les fichiers de plus de 12 mois sont supprimés. Pour les garder plus longtemps, régler Audit:RetentionMonths avant le redéploiement. Une permission personnalisée nommée feedback.read ou feedback.manage empêcherait le démarrage : la supprimer avant.
    • Administrateurs : un propriétaire donne feedback.read et feedback.manage au groupe « Administrateur » (page « Groupes et permissions »). Puis menu d'administration › « Demandes des joueurs » › le jeu.
    • Joueurs : mise à jour automatique depuis la 2.5.0, aucune action requise. Le bouton « Aide » apparaît dans la barre de titre.
    • RGPD : ajouter au registre des traitements « Demandes d'aide et retours des joueurs ». Base légale : intérêt légitime. Pas d'adresse IP. Durées : 12 mois après clôture, 24 mois au plus. Le mentionner aussi dans la politique de confidentialité.

    🔏 La sécurité des mises à jour du launcher ne change pas : la signature numérique et l'empreinte SHA-256 de chaque nouvelle version sont vérifiées avant toute installation.

    What's Changed

    Contributors

    Full Changelog: v2.5.0...v3.0.0

    Downloads