Reviewed-on: #131 Reviewed-by: Nicolas Deville <nicolas.deville@lanisys.fr>
Game Launcher — Visual Studio 2022 · C# · WPF (.NET 8)
Launcher moderne pour votre jeu : installation, mises à jour automatiques ou manuelles, réparation, vérification d'intégrité, localisation d'une installation existante, désinstallation et enregistrement dans le registre Windows.
Aperçu de l'interface : menu « … » ouvert ; docs/preview-update.png : mise à jour en cours.
Thème « exovival » (Exovival Zombie Reborn). docs/preview-multijeux.png : plusieurs jeux, thème par défaut.
1. Démarrage rapide
- Ouvrez
GameLauncher.slndans Visual Studio 2022 (17.8 ou plus récent, charge de travail Développement .NET Desktop). - Modifiez
src/GameLauncher/launcher.json: nom du jeu,gameId, et surtoutmanifestUrl(l'URL de votremanifest.jsonsur le serveur web). - Publiez une première version du jeu avec l'outil ManifestBuilder (voir §3) et envoyez le dossier produit sur votre serveur.
GameLauncherest le projet de démarrage : F5.
Pour distribuer le launcher : clic droit sur GameLauncher › Publier › profil win-x64.
Vous obtenez un GameLauncher.exe autonome (aucun runtime à installer) + launcher.json.
2. Structure de la solution
| Projet | Rôle |
|---|---|
src/GameLauncher |
Application WPF (fenêtres, thème, ViewModels, registre, raccourci) |
src/GameLauncher.Core |
Logique pure, sans WPF : manifest, téléchargement, installation, mise à jour, vérification, désinstallation, catalogue des jeux (Catalog/) |
tools/ManifestBuilder |
Outil console de publication : génère manifest.json, l'archive ZIP et le dossier objects/ |
tools/LauncherPublisher |
Outil console de publication du launcher : clés de signature, launcher-update.json signé (voir §7) |
src/GameLauncher.Contracts |
Protocole partagé launcher ⇄ Launcher API : routes, échanges, groupes et permissions, messages signés, catalogue, notes de version (modèle et limites), contrôle des manifests publiés (voir §8) |
src/GameLauncher.ApiClient |
Client de la Launcher API : connexion par clé, requêtes signées, fichier de clé chiffré |
src/GameLauncher.Modules |
Socle des modules du launcher (sans WPF) : contrat d'un module, pages du menu d'administration, MVVM commun |
src/GameLauncher.Modules.Admin |
Module « Administration » : clés, connexion, invitation, verrouillage, tableau de bord ; modules « Catalogue des jeux » (Catalog/, page « Jeux »), « Notes de version » (Changelog/) et « Publication » (Publishing/) (vues dans src\GameLauncher\Views\Admin et Themes\Admin.xaml) |
src/GameLauncher.Modules.Feedback |
Module « Aide » côté joueur (sans WPF) : formulaire de demande (avis, demande d'évolution, bug, autre) et envoi anonyme ; fenêtre dans src\GameLauncher\Views\FeedbackWindow.xaml |
server/GameLauncher.Server |
Launcher API (ASP.NET Core) : serveur d'administration, déployé sur le VPS (voir §8) |
tools/AdminKeyTool |
Clé d'administrateur et gestion des administrateurs en ligne de commande (tools\admin-key.bat) |
tools/UiSnapshot |
Captures de toutes les fenêtres (états de la fenêtre principale, dialogues, menu d'administration et ses pages) avec des données de démonstration, et rapport des problèmes de mise en page : tools\ui-snapshot.bat (voir tools\UiSnapshot\LISEZMOI.md) |
tests/GameLauncher.Tests |
Tests automatisés (xUnit) : Test › Explorateur de tests › Exécuter tout |
src/GameLauncher/
├─ App.xaml(.cs) Démarrage, instance unique, composition des services (un jeu de services par jeu)
├─ launcher.json Configuration éditeur : un jeu, ou plusieurs (voir launcher.multi-jeux.example.json)
├─ Assets/ background.png (thème par défaut), Themes/exovival-background.jpg, launcher.ico
├─ Themes/ Default.xaml et Exovival.xaml (thèmes), Icons.xaml (icônes), Controls.xaml (styles),
│ Changelog.xaml (modèles des notes de version), Admin.xaml (menu d'administration,
│ dont les pages « Jeux », « Notes de version » et « Publier une version »)
├─ Views/ MainWindow (+ liste des jeux), InstallDialog, SettingsWindow, ChangelogWindow, ModernDialog, TrayMenuWindow,
│ FeedbackWindow (bouton « Aide »)
│ └─ Admin/ AdminWindow, LoginView, EnrollView (menu d'administration ; ViewModels dans GameLauncher.Modules.Admin)
├─ ViewModels/ LauncherViewModel (jeux, thème actif, paramètres du launcher),
│ GameViewModel (machine à états d'un jeu),
│ LauncherSettingsViewModel / GameSettingsViewModel (les deux fenêtres de paramètres)
├─ Services/ ThemeManager, RegistryService, ShortcutService, InstanceChannel (raccourci → launcher
│ déjà ouvert), GameScopedServices, AdminWindowService (menu d'administration),
│ FeedbackWindowService (bouton « Aide »), interfaces
└─ Platform/ DialogService, WindowService (implémentations WPF), TrayIcon (zone de notification),
ModuleDialogs, WpfUiDispatcher (services offerts aux modules)
3. Publier une version du jeu (ManifestBuilder)
dotnet run --project tools\ManifestBuilder -c Release -- ^
--source "D:\Builds\MonJeu" ^
--output "D:\Publish\MonJeu" ^
--version 1.0.1 ^
--exe MonJeu.exe ^
--game-id MonJeu ^
--notes notes.txt ^
--remote-manifest https://launcher.example/monjeu/manifest.json ^
--exclude "*.pdb;*.log"
L'historique des notes est conservé d'une version à l'autre (30 versions) et affiché dans le launcher (panneau « Notes de version », bouton Agrandir pour les lire en grand).
--remote-manifest (recommandé, déjà dans tools\publish-example.bat) : l'historique est repris du
manifest en ligne, et non du manifest.json local. Les notes corrigées depuis le menu
d'administration (page « Notes de version », §8) ne sont donc pas écrasées à la publication
suivante. Pas de manifest en ligne (première publication) : historique local. Serveur injoignable :
la publication s'arrête (rien n'est perdu ; réessayez, ou retirez l'option). Envoyez ensuite les
fichiers sans attendre. Republier une version sans --notes garde ses notes existantes.
Mise en ligne : depuis le menu d'administration, page Publier une version (§8) : choisissez le
manifest.json du dossier --output, puis « Publier ». Seuls les fichiers absents du serveur sont
envoyés, l'envoi reprend après une coupure, et le manifest est mis en ligne en dernier. WinSCP reste
possible (objects/ et l'archive d'abord, manifest.json en dernier), mais pas les deux en même temps.
Format de notes.txt
Texte simple, à écrire comme une note de mise à jour (exemple complet : tools/notes.txt) :
# Version 1.2 ← titre (première ligne « # … »)
EXOVIVAL ZOMBIE REBORN - NOTES DE MISE A JOUR ← lignes soulignées de ===== : sous-titre
Niveau 1 « L'école » - Mise à jour du 17 octobre 2026
==================================================
Merci aux bêta-testeurs ! ← paragraphe avant la 1re section : introduction
--------------------------------------------------
ÉNIGMES ← titre de section : encadré de -----,
-------------------------------------------------- souligné de -----, ou « ## Titre »
Plusieurs objets étaient mal placés : ← paragraphe sans tiret : commentaire
- Labyrinthe : ses commandes ont été ← « - », « * » ou « • » : une modification
corrigées. ← ligne indentée : suite du texte
- NOUVEAU : consommation de carburant. ← « MOT EN MAJUSCULES : » ou « [Mot] » : étiquette
* les appareils déjà utilisés restent actifs ; ← puce indentée : sous-point
Trouvez un autre jerrican. ← texte indenté après les sous-points : note
L'ancien format (# Titre puis une modification par ligne, sans tiret) reste accepté. Le
manifest contient aussi la liste « à plat » historique (changes) : les launchers antérieurs
au format enrichi continuent d'afficher les notes. Côté launcher, les notes reçues du serveur
sont bornées (nombre de versions, de sections, longueur des textes) et nettoyées des caractères
de contrôle avant affichage.
Le dossier --output contient :
manifest.json ← version, exécutable, liste des fichiers (taille + SHA-256), notes de version
MonJeu-1.0.1.zip ← archive complète, utilisée pour la première installation
objects/ab/abcd….bin ← chaque fichier du jeu, nommé par son empreinte SHA-256
Gardez ce dossier entre deux versions : seuls les fichiers modifiés sont ajoutés à objects/,
il n'y a donc que les nouveautés à envoyer. Ordre d'envoi : objects/ et le .zip d'abord,
manifest.json en dernier (les joueurs ne voient ainsi jamais une version incomplète).
Pourquoi des fichiers nommés par empreinte ? Un fichier identique n'est jamais stocké deux fois,
les anciens fichiers restent disponibles pour un joueur en pleine mise à jour, et l'extension
.bin évite les blocages de certains serveurs (IIS refuse par exemple de servir les .config).
Exemples de configuration serveur : server-example/ (nginx, Apache, IIS). Le point important :
manifest.json ne doit pas être mis en cache.
4. Fonctionnement
Détection au démarrage
| Situation | État affiché | Bouton principal |
|---|---|---|
| Aucune clé dans le registre | Non installé | INSTALLER (+ lien « Localiser l'installation ») |
| Clé présente, fichiers présents, version = serveur | Installé | JOUER |
| Version locale ≠ version du serveur | Mise à jour disponible | METTRE À JOUR (automatique si activé) |
| Clé présente mais dossier/exécutable supprimé à la main | Installation introuvable | RÉPARER (+ Localiser / Oublier) |
| Vérification d'intégrité en échec | Réparation nécessaire | RÉPARER |
| Serveur injoignable | Installé · hors ligne | JOUER |
Installation initiale
Choix du dossier (contrôle de l'espace disque et des droits d'écriture) → téléchargement de l'archive ZIP (reprise possible après annulation ou coupure) → contrôle SHA-256 → extraction (protégée contre le « zip slip ») → vérification de chaque fichier → écriture du registre → raccourci bureau (optionnel).
Mise à jour (automatique ou manuelle)
Comparaison fichier par fichier avec le manifest. Seuls les fichiers manquants ou différents
sont téléchargés (en parallèle, avec nouvelles tentatives), vérifiés, puis mis en place. Les
fichiers supprimés dans la nouvelle version sont retirés ; les sauvegardes du joueur sont
conservées. Un cache d'empreintes (.launcher/state.json) évite de relire tout le jeu à chaque
lancement. Recherche de mise à jour : au démarrage, toutes les 30 min (configurable), à la
fermeture du jeu, ou depuis le menu « … ».
Vérification d'intégrité
Recalcul du SHA-256 de tous les fichiers. En cas d'écart, le launcher propose une réparation qui ne retélécharge que les fichiers concernés. Hors ligne, la vérification utilise les empreintes enregistrées localement.
Réparation
Si le dossier a disparu ou est presque vide → réinstallation via l'archive ZIP dans le même dossier. Sinon → vérification complète + téléchargement des seuls fichiers défectueux.
La réparation contrôle aussi les raccourcis du Bureau du jeu et l'entrée « Applications installées » de Windows (voir « Raccourcis du Bureau » ci-dessous) : s'ils désignent un ancien emplacement du launcher, ils sont redirigés vers le launcher actuel (même hors ligne).
Raccourcis du Bureau et déplacement du launcher
Le raccourci créé à l'installation pointe vers le launcher (GameLauncher.exe --game <GameId>),
pas vers le jeu : les mises à jour sont ainsi toujours vérifiées. Un raccourci « du jeu » est
reconnu à ses arguments --game <GameId>, même si le joueur l'a renommé (Bureau de l'utilisateur).
- Créer le raccourci : à l'installation (case à cocher), ou à tout moment depuis le menu « … » › Paramètres du jeu › bloc Raccourci (« Créer le raccourci », ou « Mettre à jour » s'il existe déjà).
- Icône : celle de l'exécutable du jeu (dossier d'installation et exécutable lus dans le registre), ou celle du launcher si le jeu n'est pas installé ou introuvable. Elle suit le jeu s'il est déplacé (localisation, réparation) ; les raccourcis créés par une version précédente prennent l'icône du jeu au démarrage du launcher. Une icône choisie par le joueur n'est jamais remplacée.
- Nom : le nom affiché du jeu (page « Jeux » du menu d'administration), sinon celui de
launcher.json. Un raccourci nommé par le launcher est renommé quand ce nom change : au démarrage du launcher, avec « Mettre à jour » (Paramètres du jeu › Raccourci) et avec Réparer. Un raccourci renommé par le joueur garde son nom, et aucun fichier existant du Bureau n'est remplacé (le nom delauncher.jsonest alors conservé).
| Situation | Comportement |
|---|---|
| Raccourci ouvert, launcher fermé | Le launcher s'ouvre sur ce jeu, vérifie les mises à jour (et les installe si la mise à jour automatique du jeu est activée), puis lance le jeu s'il est prêt, en appliquant le réglage Lancement du jeu (réduire / fermer le launcher). Sinon le bandeau explique pourquoi (mise à jour manuelle à faire, réparation, jeu non installé). Hors ligne, le jeu installé est lancé. |
| Launcher déplacé ou renommé, raccourci vers l'ancien emplacement (fichier disparu) | Au prochain démarrage du launcher depuis son nouvel emplacement : raccourci redirigé automatiquement, LauncherPath et bouton « Désinstaller » de Windows mis à jour |
| Raccourci vers un autre exemplaire du launcher, encore présent (copie) | Rien d'automatique ; Réparer propose de le rediriger (confirmation) |
| Icône personnalisée par le joueur | Conservée lors de la redirection |
| Raccourci ouvert alors que le launcher est déjà ouvert | La demande est transmise au launcher ouvert : il revient au premier plan sur ce jeu et lance le jeu s'il est prêt et pas déjà en cours d'exécution (sinon le bandeau explique pourquoi : mise à jour, réparation, opération en cours…). Rien n'est lancé si une boîte de dialogue est ouverte. |
Launcher relancé sans --game alors qu'il est déjà ouvert |
Message « Le launcher est déjà ouvert » (qui rappelle de regarder dans la zone de notification) |
| Raccourci ouvert alors que le launcher est réduit dans la zone de notification | La fenêtre est réaffichée, puis même comportement que « déjà ouvert » |
Tant que le launcher n'a pas été relancé depuis son nouvel emplacement, un raccourci vers l'ancien
emplacement ne fonctionne pas (Windows le signale, et le retrouve parfois tout seul). Le chemin du
launcher est enregistré dans le registre (LauncherPath, UninstallString) pour chaque jeu
installé et mis à jour à chaque démarrage. Les paramètres (%AppData%) ne dépendent pas de
l'emplacement du launcher ; un launcher.json posé à côté de l'exe doit être déplacé avec lui.
Lancer le jeu, avec ou sans raccourci, ne démarre pas une seconde copie du jeu si son exécutable tourne déjà (lancé directement ou avant un redémarrage du launcher).
Communication entre instances : canal nommé local réservé à l'utilisateur courant
(PipeOptions.CurrentUserOnly, nom propre à la session et à l'utilisateur), une seule commande
bornée (256 octets, 2 s) contenant uniquement un identifiant de jeu, validé puis comparé aux jeux
de launcher.json. Aucun chemin ni argument n'est transmis. Le canal est fermé avant le
redémarrage du launcher lors de sa mise à jour, puis recréé par la nouvelle version.
Localiser le jeu
Sélection d'un dossier : l'exécutable est recherché dans le dossier et ses sous-dossiers (2 niveaux). Le jeu est enregistré dans le registre puis analysé : s'il diffère de la dernière version, une mise à jour (différentielle) est proposée.
Désinstallation
Depuis le menu « … » ou depuis Paramètres Windows › Applications installées (le launcher est
relancé avec --uninstall <GameId>). Par défaut seuls les fichiers installés par le launcher sont
supprimés : les sauvegardes et réglages du jeu (%APPDATA%\<Société>\<Produit>) et les fichiers
personnels du dossier d'installation sont conservés.
L'option « Supprimer aussi les sauvegardes, les réglages, les journaux et tous les autres fichiers du jeu » (proposée aussi quand les fichiers du jeu ont déjà disparu) supprime en plus :
| Élément | Emplacement |
|---|---|
| Tout le dossier d'installation | refusé pour les dossiers sensibles : racine de disque, Program Files, Documents… |
| Sauvegardes et réglages | %APPDATA%\LanisysGames\Exovival Zombie Reborn |
Journaux de Unity (Player.log) |
%USERPROFILE%\AppData\LocalLow\LanisysGames\Exovival Zombie Reborn |
| Réglages d'affichage de Unity (résolution, plein écran, position de la fenêtre) | HKCU\Software\LanisysGames\Exovival Zombie Reborn |
Garde-fous : chemin « Société\Produit » complet uniquement (gameDataFolder, jamais le dossier de la
société entier), jamais le dossier ni la clé du launcher (GameLauncher) ni le dossier d'installation ;
dossier et clé de la société retirés seulement s'ils sont vides. Ce qui n'a pas pu être supprimé (fichier
ouvert) est indiqué dans le bandeau et le journal.
Launcher placé dans un dossier supprimé — dossier du jeu, ou (avec l'option) dossier des sauvegardes dans
Roaming ou des journaux dans LocalLow, à toute profondeur : la confirmation l'indique (« Le launcher se trouve
dans ce dossier / dans le dossier des données du jeu : il sera conservé. ») et ses fichiers sont épargnés :
son exécutable, launcher.json, les fichiers temporaires de sa mise à jour (GameLauncher.exe.old,
.download…) et, en version de développement, les bibliothèques chargées depuis son dossier. Tout le reste
est supprimé, les sous-dossiers vides sont retirés, et le bandeau final indique où le launcher a été conservé.
Les trois dossiers suivent la même règle (FileUtil.DeleteDirectoryContents).
Fichier bloqué (jeu mal fermé, antivirus…) : la désinstallation ne s'interrompt plus. Les fichiers sont supprimés un par un ; ceux qui ne peuvent pas l'être sont signalés (bandeau + liste complète dans le journal), puis registre, raccourci et données du jeu sont traités normalement.
Registre (HKEY_CURRENT_USER, aucun droit administrateur requis)
HKCU\Software\<Publisher>\GameLauncher (ex. …\LanisysGames\GameLauncher)
LauncherPath emplacement du launcher (une seule fois)
HKCU\Software\<Publisher>\GameLauncher\Games\<GameId> (ex. …\GameLauncher\Games\EZR)
InstallPath, Version, Executable, InstallDate
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\<Publisher>.<GameId>
DisplayName, DisplayVersion, Publisher, InstallLocation, DisplayIcon,
UninstallString ("GameLauncher.exe" --uninstall <GameId>), EstimatedSize…
LauncherPathest écrit une seule fois pour tous les jeux, à l'installation d'un jeu et à chaque démarrage (s'il y a au moins un jeu installé), et supprimé à la désinstallation du dernier jeu. Seul le launcher réellement ouvert l'écrit : un second launcher, arrêté par « Le launcher est déjà ouvert » (ou qui transmet un raccourci au launcher ouvert), ne touche pas au registre. Il est informatif : la vérification des raccourcis compare la cible de chaque raccourci à l'exécutable en cours, pas au registre.
Paramètres
Deux fenêtres distinctes :
| Accès | Contenu | Portée |
|---|---|---|
| Roue crantée (en haut à droite) › Paramètres du launcher | Mise à jour automatique du launcher, « Vérifier les mises à jour », bloc Lancement du jeu (réduire — dans la barre des tâches ou la zone de notification — ou fermer le launcher pendant la partie), bloc Fermeture du launcher (la croix ferme ou réduit dans la zone de notification), dossier des journaux | Commun à tous les jeux |
| Menu « … » › Paramètres du jeu | Mises à jour automatiques du jeu, bloc Téléchargement (téléchargements simultanés, vérification après installation), bloc Raccourci (créer / mettre à jour le raccourci du Bureau), bloc Informations (versions, taille ; boutons dossier du jeu, dossier des journaux du jeu dans LocalLow, dossier des données du jeu dans Roaming) | Jeu sélectionné uniquement |
Au premier démarrage d'une version qui sépare les paramètres, les réglages Lancement du jeu sont repris de ceux du jeu affiché par défaut.
Plein écran
La fenêtre principale et le menu d'administration ont deux modes : fenêtré (taille d'origine) ou plein écran (fenêtre agrandie sur tout l'écran, la barre des tâches restant visible). Bascule : bouton entre « Réduire » et « Fermer », ou F11. Le mode de chaque fenêtre est retenu pour la fois suivante. Les fenêtres ne se redimensionnent jamais par les bords ou les coins ; la mise en page s'adapte à la place disponible (plein écran : colonnes plus larges ; petit écran ou mise à l'échelle 125-150 % : contenu réduit d'un bloc, sans rien rogner). Les autres fenêtres (paramètres, notes de version agrandies, boîtes de dialogue) gardent leur taille fixe.
Zone de notification (icônes cachées, près de l'horloge)
Deux options des Paramètres du launcher (désactivées par défaut) :
| Option | Effet |
|---|---|
| Lancement du jeu › Réduire le launcher pendant la partie › Dans la zone de notification | Pendant la partie, la fenêtre est masquée et une icône apparaît près de l'horloge ; la fenêtre revient à la fermeture du jeu |
| Fermeture du launcher › La croix réduit le launcher dans la zone de notification | La croix (et Alt+F4) masque la fenêtre au lieu de quitter : téléchargements, mises à jour et surveillance du jeu continuent |
L'icône n'est affichée que lorsque la fenêtre est masquée. Clic gauche : réouvre le launcher.
Clic droit : menu Ouvrir / Quitter (même style arrondi que les autres menus, couleurs du thème
du jeu affiché). Quitter demande confirmation si une opération est en cours (la fenêtre est alors
réaffichée). À la fermeture de session ou à l'arrêt de Windows, le launcher se ferme normalement.
L'icône est gérée par l'API Windows (Shell_NotifyIcon, Platform/TrayIcon.cs), sans Windows Forms,
et réapparaît si l'Explorateur Windows redémarre. Le menu est une petite fenêtre (Views/TrayMenuWindow)
et non un ContextMenu WPF : launcher masqué, un ContextMenu ne peut pas capturer la souris et se
referme aussitôt. Il se ferme dès qu'il perd le premier plan (clic ailleurs) ou avec Échap.
Autres fichiers
%AppData%\<Publisher>\GameLauncher (ex. %AppData%\LanisysGames\GameLauncher)
├─ launcher-settings.json paramètres du launcher (communs à tous les jeux)
├─ self-update.json mise à jour du launcher (§7)
├─ launcher-state.json dernier jeu affiché (plusieurs jeux)
├─ window-modes.json plein écran ou fenêtré, par fenêtre (« main », « admin »)
├─ logs\launcher.log journal du launcher (roue crantée › Ouvrir le dossier des journaux)
└─ Games\<GameId>\settings.json paramètres de chaque jeu (menu « … » › Paramètres du jeu)
- État de l'installation :
<dossier du jeu>\.launcher\state.json(dossier caché) - Nom du dossier et de la clé de registre :
launcher.json→"dataFolder"(à la racine ;"GameLauncher"par défaut). Il est indépendant delauncherId, qui ne doit plus changer (§7).
Versions 1.2.1 et antérieures : les données étaient dans %AppData%\<Publisher>\<LauncherId> (ex.
EZRLauncher, + <GameId>Launcher par jeu en multi-jeux) et dans HKCU\Software\<Publisher>\<GameId>.
Au démarrage, le launcher les déplace (renommage du dossier, paramètres de chaque jeu vers Games\<GameId>,
copie vérifiée puis suppression de l'ancienne clé de registre). Ce déplacement n'a lieu que si aucun autre
launcher n'est ouvert, et jamais au redémarrage qui suit une mise à jour du launcher (l'ancienne version doit
pouvoir être remise en place) : l'ancien emplacement est alors utilisé pour la session et le déplacement est
fait au démarrage suivant. Les entrées Applications installées (Uninstall\<Publisher>.<GameId>) ne changent pas.
Données du jeu (Unity)
| Contenu | Emplacement | Bouton (Paramètres du jeu › Informations) |
|---|---|---|
Sauvegardes (Data\SavedGame) et réglages (Data\Config) |
%APPDATA%\LanisysGames\Exovival Zombie Reborn (Roaming, à côté de GameLauncher) |
Ouvrir le dossier des données |
Journaux de Unity (Player.log, Player-prev.log) |
%USERPROFILE%\AppData\LocalLow\LanisysGames\Exovival Zombie Reborn |
Ouvrir le dossier des journaux |
- « LanisysGames\Exovival Zombie Reborn » correspond à Company Name / Product Name des Player Settings
de Unity ; côté launcher :
launcher.json→gameDataFolder(par défautpublisher\gameName). - Le jeu choisit l'emplacement dans
SerializationAsset.cs(UHFPS, classeExovivalDataLocation). Au premier lancement d'une version qui l'intègre, le dossierDatade LocalLow est copié vers Roaming, vérifié (mêmes fichiers, mêmes tailles), puis supprimé de LocalLow. En cas d'échec, le jeu continue d'utiliser LocalLow et réessaie au lancement suivant. Dans l'éditeur Unity, rien ne change (Assets/Data). Player.logreste dans LocalLow : son emplacement est fixé par Unity (Application.persistentDataPath).
5. Personnalisation
| Quoi | Où |
|---|---|
| Thème d'un jeu | launcher.json → "theme": "default", "exovival" ou "Themes\\MonTheme.xaml" |
| Couleurs d'un thème | Themes/Default.xaml (contrat complet), Themes/Exovival.xaml (clés redéfinies) |
| Illustration de fond | Clé BackgroundImage du thème, ou launcher.json → "background" pour un seul jeu (1600×900 minimum, sujet à droite) |
| Vignette d'un jeu (liste des jeux) | launcher.json → "icon" (image carrée) ; sinon fond du thème + initiales |
| Icône | Remplacez Assets/launcher.ico |
| Icônes de l'interface | Themes/Icons.xaml (tracés 24×24, compatibles Material Design Icons) |
| Vérifier un réglage graphique | tools\ui-snapshot.bat (ex. --filter "main-*" --scale 2) : un PNG par écran dans artifacts\ui-snapshots, planche index.html, problèmes détectés dans report.md |
| Textes | launcher.json (nom, accroche), ViewModels/GameViewModel.cs ; sans recompiler : menu d'administration › Jeux (§8) |
| Fréquence des recherches de mises à jour | launcher.json → updateCheckIntervalMinutes |
| Dossier des données du jeu Unity (« Société\Produit ») | launcher.json → gameDataFolder |
Thèmes
Le thème suit le jeu sélectionné : changer de jeu change instantanément l'apparence (fondu enchaîné). Thèmes fournis :
| Nom | Apparence |
|---|---|
default |
Violet / cyan, illustration Assets/background.png (apparence d'origine) |
exovival |
Exovival Zombie Reborn : noir profond, couloir de l'école dans le noir (capture du niveau 1, lampe torche et bloc de secours vert), accent vert néon, titre en Bahnschrift condensée, logo « risque biologique » |
Créer un thème : copiez Themes/Exovival.xaml, gardez uniquement les clés à changer (les
autres reprennent Default.xaml), puis :
- thème intégré : ajoutez le fichier au projet, son image dans
Assets/Themes/, et une ligne dansThemeManager.BuiltIn; - ou thème externe, sans recompiler : déposez le
.xamlà côté deGameLauncher.exeet indiquez son chemin dans"theme"(images en chemin absolu oupack://siteoforigin:,,,/…).
Toutes les vues utilisent {DynamicResource …} pour les couleurs, polices et fonds :
n'utilisez pas StaticResource pour une clé de thème, elle ne changerait plus avec le jeu.
Plusieurs jeux
Remplacez le contenu de launcher.json par le format de launcher.multi-jeux.example.json :
une liste "games", et à la racine les valeurs communes (publisher, websiteUrl…). Une
liste des jeux apparaît alors à gauche de la fenêtre (masquée s'il n'y a qu'un jeu).
- Chaque jeu garde son entrée de registre, son raccourci, ses paramètres et ses mises à jour : rien ne change pour un jeu déjà installé avec la version mono-jeu.
- Les jeux sont vérifiés en parallèle ; une pastille sur la vignette signale une mise à jour, une opération en cours ou un problème. Un message concernant un jeu sélectionne ce jeu.
- Raccourci du Bureau :
GameLauncher.exe --game <GameId>(ouvre le launcher sur ce jeu et le lance s'il est prêt). - Fermer le launcher pendant des téléchargements demande une seule confirmation pour tous les jeux.
Options de la ligne de commande
| Option | Rôle |
|---|---|
--game <GameId> |
Ouvre le launcher sur ce jeu, vérifie les mises à jour puis lance le jeu s'il est prêt ; si le launcher est déjà ouvert, lui demande de lancer ce jeu (voir « Raccourcis du Bureau ») |
--uninstall [GameId] |
Désinstallation (utilisée par Windows) |
--config <fichier> |
Utilise un autre launcher.json (tests). En Release, ses apiUrl et catalogUrl sont ignorées (seules celles intégrées à l'exe comptent) |
--capture <dossier> |
Enregistre une capture PNG par jeu (+ ses paramètres, + paramètres du launcher), sans rien installer, puis quitte |
--updated <pid> <événement> <version> |
Interne : démarrage de la nouvelle version après une mise à jour du launcher (§7). Le jeu de --game n'est alors lancé que si --launch est aussi présent (mise à jour faite au démarrage depuis un raccourci), jamais après une mise à jour demandée depuis les paramètres |
6. Bon à savoir
- Le dossier proposé par défaut est
C:\Games\<Nom du jeu>. Installer dans Program Files nécessiterait de lancer le launcher en administrateur ; le dialogue d'installation le signale. - Le serveur doit accepter les requêtes
Range(c'est le cas par défaut de nginx, Apache et IIS) pour la reprise des téléchargements ; sinon le téléchargement repart simplement de zéro. - Les icônes proviennent de Material Design Icons (licence Apache 2.0).
7. Mise à jour du launcher
Le launcher (un seul GameLauncher.exe) vérifie au démarrage s'il existe une version plus récente de
lui-même, la télécharge, l'installe et redémarre tout seul. Réglable dans Paramètres du launcher (roue crantée) :
interrupteur « Mettre à jour le launcher automatiquement » (commun à tous les jeux) et bouton
« Vérifier les mises à jour » (puis « Installer la x.y.z »). Option désactivée : un bandeau signale
simplement qu'une nouvelle version existe.
Sécurité
| Protection | Effet |
|---|---|
Signature ECDSA P-256 de launcher-update.json |
La clé privée reste sur votre PC (chiffrée par une phrase de passe) ; la clé publique est intégrée à l'exe. Un pirate qui prendrait le contrôle du VPS ne peut pas distribuer de faux launcher. |
| SHA-256 + taille de l'exe dans la partie signée | Le fichier téléchargé est refusé (et supprimé) s'il diffère d'un seul octet. |
| HTTPS obligatoire | Une adresse http:// est refusée (sauf localhost, pour les tests). |
| Pas de rétrogradation | Seule une version strictement supérieure est installée ; le produit (launcherId) doit correspondre. |
| Tailles bornées | launcher-update.json ≤ 256 Ko ; un serveur qui envoie plus que la taille annoncée est coupé (vaut aussi pour les fichiers du jeu). |
| Retour arrière automatique | Si la nouvelle version ne démarre pas dans les 60 s (ou n'est pas la version annoncée), elle est arrêtée et l'ancienne remise en place. Cette version n'est plus proposée automatiquement (bouton manuel uniquement). |
Déroulement
GameLauncher.exe (1.0.0) ── lit launcher-update.json ── vérifie la signature
│ télécharge GameLauncher-1.1.0.exe à côté : GameLauncher.exe.1.1.0.download (reprise possible)
│ vérifie taille + SHA-256
│ GameLauncher.exe → GameLauncher.exe.old (Windows autorise à renommer un exe en cours d'exécution)
│ GameLauncher.exe.1.1.0.download → GameLauncher.exe
└─ lance GameLauncher.exe --updated … ──► 1.1.0 s'affiche, prévient 1.0.0, qui se ferme ; .old supprimé
La nouvelle version s'appelle toujours GameLauncher.exe, même si l'exe en cours a été renommé
(par exemple GameLauncher-1.0.0.exe, le nom du fichier publié sur le serveur) : l'ancien fichier part en
GameLauncher.exe.old, et une autre copie qui portait déjà ce nom est mise de côté en
GameLauncher.exe.replaced (remise en place en cas d'échec, supprimée sinon). Au démarrage suivant,
l'entrée « Applications installées » est mise à jour, ainsi que le raccourci du Bureau s'il pointait vers
l'ancien nom.
La mise à jour est refusée tant qu'un jeu est lancé ou qu'un téléchargement est en cours. Si le launcher
est dans un dossier protégé (Program Files), il ne peut pas se remplacer : le message l'explique.
Depuis Visual Studio (F5), le bouton vérifie mais n'installe pas : seule la version publiée se remplace.
Mise en place (une seule fois)
- Clés : double-cliquez
tools\keygen-launcher.bat. Choisissez une phrase de passe (12 caractères minimum). La clé privée est créée dans%USERPROFILE%\.launcher-keys\launcher-signing.key— sauvegardez-la (clé USB, gestionnaire de mots de passe), ne la mettez jamais dans Git ni sur le serveur. La clé publique est copiée danssrc\GameLauncher\Security\update-signing.pub. - Adresse :
launcher.json→"launcherUpdateUrl": "https://…/launcher/launcher-update.json". - VPS (compte admin) :
sh server-example/launcher/preparer-vps.shcrée/srv/exovival/www/launcher, puis ajoutezserver-example/launcher/nginx-launcher.confdans le bloc HTTPS du site (sudo nginx -t && sudo systemctl reload nginx). - WinSCP : copiez
server-example/launcher/publier-launcher.txtdansB:\Unity\, avec la même ligneopen …que votrepublier.txt(comptedeploy). - Publiez le launcher et distribuez cette version à la main une dernière fois : les suivantes arriveront toutes seules.
Publier une nouvelle version du launcher
- Augmentez
<Version>danssrc\GameLauncher\GameLauncher.csproj(ex.1.0.0→1.1.0). - Écrivez les nouveautés dans
tools\notes-launcher.txt, au même format que les notes du jeu (titre, sous-titre souligné de=====, introduction, sections encadrées de-----,-pour une modification,NOUVEAU :pour une étiquette, puce indentée pour un sous-point : voir « Format denotes.txt» au §3). La fenêtre de mise à jour les affiche comme les notes du jeu (bouton Agrandir compris), avec les notes de toutes les versions publiées depuis celle du joueur. L'historique (30 versions, 256 Ko au plus) est repris dulauncher-update.jsonprécédent s'il est signé par votre clé. Les launchers antérieurs à 1.1.3 reçoivent toujours le titre et la liste « à plat ». - Double-cliquez
tools\publish-launcher-update.bat: compilation, signature (phrase de passe demandée), puis envoi WinSCP — l'exe d'abord,launcher-update.jsonen dernier.
Vérification à tout moment :
dotnet run --project tools\LauncherPublisher -- verify --manifest https://…/launcher/launcher-update.json --public-key src\GameLauncher\Security\update-signing.pub
Changer de clé (clé perdue ou compromise) : ajoutez la nouvelle clé publique à la suite de l'ancienne
dans update-signing.pub, publiez une version signée avec l'ancienne clé, puis signez les suivantes avec
la nouvelle. Ne modifiez plus launcherId (ni le format mono/multi-jeux qui le détermine) une fois le
launcher distribué : c'est l'identifiant de produit vérifié lors des mises à jour.
Fichiers
- Préférences :
%AppData%\<Publisher>\GameLauncher\self-update.json(autoUpdate, version en échec, dernière recherche) - À côté de l'exe, temporairement :
GameLauncher.exe.<version>.download,GameLauncher.exe.old,GameLauncher.exe.replaced,GameLauncher.exe.failed
8. Administration (Launcher API)
Chantier en cours, découpé en phases : architecture, sécurité et planning dans
docs/ADMIN-ARCHITECTURE.md. Phase 1 livrée : le serveur d'administration et ses outils.
Phase 2 livrée : le menu d'administration du launcher (connexion, invitation, tableau de bord).
Phase 3 livrée : la page Jeux (catalogue des jeux, voir plus bas). Phase 4 livrée : la page
Notes de version. Phase 5 livrée : la page Publier une version. Phase 6 livrée : les pages
Mes appareils, Administrateurs et Journal d'audit. Phase 7 livrée : la signature du contenu
servi aux joueurs (page Signature, voir plus bas). Ajoutées ensuite : la page Fichiers du serveur, puis le
bouton Aide des joueurs et la page Demandes des joueurs (voir plus bas).
-
Ergonomie commune aux pages : les boutons d'action (« Recharger », « Publier », « Enregistrer », « Actualiser », « Exporter… ») restent affichés en bas de la fenêtre, quelle que soit la position dans la page ; après « Recharger » ou « Publier », la page remonte en haut pour montrer le bandeau du résultat. La molette fait défiler ce qui est sous le curseur : elle ne change jamais une liste déroulante fermée (même si elle vient d'être utilisée), et une liste ou un champ qui ne peut plus défiler laisse défiler la page.
-
Bouton « Aide » (joueurs, barre de titre, bulle avec un point d'interrogation) : avis, demande d'évolution, bug ou autre, pour le jeu sélectionné (affiché, non modifiable pendant la saisie). Champs prédéfinis selon le type (note en étoiles, catégorie, gravité, fréquence, étapes pour reproduire…), contrôlés avant l'envoi avec les règles du serveur ; informations techniques facultatives (versions, Windows, langue) montrées avant l'envoi, cochées par défaut pour un bug. Demande anonyme : aucun compte, aucune adresse IP enregistrée ; le joueur reçoit une référence
FB-XXXX-XXXX. En cas d'échec (réseau, serveur), la saisie est conservée. Bouton absent sansapiUrl; réception à activer sur le serveur (server/deploy/LISEZMOI.md, étape 3 octies). -
Page « Demandes des joueurs » (permission
feedback.read; traitement :feedback.manage) : choix du jeu (nombre de nouvelles demandes sur chaque tuile), filtres (type, statut, recherche), fiche complète, statut (Nouvelle, En cours, Traitée, Rejetée, Doublon), note interne, suppression. Chaque consultation est inscrite au journal d'audit. Purge automatique : 12 mois après la clôture, 24 mois au plus ; le journal d'audit est purgé au-delà de 12 mois. -
Ouvrir le menu :
Ctrl+Maj+Alt+Adans la fenêtre du launcher, ou 5 clics rapides (en moins de 3 s) sur le logo en haut à gauche. Accès discret, pas secret : seule la connexion par clé, vérifiée par le serveur, protège l'administration. -
Adresse du serveur :
"apiUrl"danssrc\GameLauncher\launcher.json(racine du fichier, https). En Release, seule la valeur intégrée à l'exe est utilisée ; en Debug, celle dulauncher.jsonutilisé (ex.--configavechttp://127.0.0.1:5080/api/pour un serveur local). SansapiUrl, le menu indique qu'il n'est relié à aucun serveur. -
Se connecter : choisir sa clé (dossier
%USERPROFILE%\.launcher-keys, ou « Choisir un autre fichier de clé… »), saisir sa phrase de passe. Verrouillage automatique après 10 min sans activité, quand Windows est verrouillé, ou avecCtrl+L; fermer la fenêtre efface la clé de la mémoire. -
« J'ai une invitation » : crée la clé sur ce PC et l'enregistre avec le code reçu, puis affiche l'empreinte à dicter à la personne qui approuve. Sans code : clé seule (premier propriétaire, à déclarer sur le VPS). Deux rangements au choix :
- fichier chiffré (phrase de passe, 12 caractères min.) : copiable et sauvegardable ;
- puce de sécurité (TPM 2.0) de ce PC (code PIN, 6 caractères min.) : la clé est créée dans la
puce et ne peut pas être copiée. Proposé seulement après vérification réelle de la puce. Elle
disparaît avec la puce (carte mère, réinitialisation, Windows réinstallé) : gardez aussi une
clé fichier de secours. Sur le disque :
admin.tpmkey(référence, sans secret) etadmin.pub. Écran de connexion : « Supprimer cette clé de la puce » (puis révoquer la clé sur le serveur) ; après trop de codes PIN faux, un décompte indique quand la puce acceptera de nouveau un code (blocage lu dans la puce : attributinLockoutet compteur d'erreursTPM_PT_LOCKOUT_COUNTER).
-
Page « Jeux » (permission
games.edit) : nom affiché, accroche, description, liens (Discord, YouTube…), site, thème intégré, icône et fond (bouton « Parcourir… » : l'image choisie dans l'explorateur Windows est contrôlée puis envoyée au serveur, sans client FTP ; aperçu, adresse renseignée automatiquement), fréquence des recherches de mise à jour, jeu masqué, nom du launcher, jeu affiché au premier lancement, ordre des jeux. Champ vide = valeur delauncher.json. « Publier » contrôle les valeurs puis écritcatalog.jsonsur le serveur (requête signée) ; si quelqu'un a publié entre-temps, rien n'est écrasé et la page propose de recharger. Les jeux eux-mêmes (identifiant, manifest, exécutable, dossiers) restent danslauncher.json; le nom affiché renomme le raccourci du Bureau (voir « Raccourcis du Bureau »), mais ni le registre, ni les dossiers. Le nom du launcher apparaît dans les paramètres du launcher (roue crantée), l'info-bulle de l'icône de la zone de notification et, avec plusieurs jeux, le titre de la fenêtre (barre des tâches) ; avec un seul jeu, l'en-tête montre le nom du jeu. Le catalogue publié est pris en compte au démarrage suivant du launcher. -
Page « Notes de version » (permission
changelog.edit) : corrige les notes des versions déjà publiées dans lemanifest.jsondu serveur. Liste des versions, en-tête (titre, sous-titre, introduction), sections › éléments (modification ou commentaire, étiquette, sous-points, note), boutons ↑ ↓ pour l'ordre, Aperçu avec la présentation exacte du launcher. Mêmes limites que le launcher, vérifiées avant l'envoi. « Enregistrer » ne change que les notes (fichiers, archive, version et exécutable restent identiques) ; si le manifest a changé entre-temps (nouvelle version publiée), rien n'est écrasé et la page propose de recharger. Une nouvelle version et ses notes se publient toujours avec ManifestBuilder (§3,--remote-manifest). Installation sur le VPS :server/deploy/LISEZMOI.md, étape 3 ter. -
Plusieurs jeux (pages « Notes de version » et « Publier une version ») : la page s'ouvre sur le choix du jeu (une tuile par jeu de
launcher.json, aucun jeu par défaut) et n'affiche rien d'autre avant ce choix ; une liste « Jeu » permet ensuite d'en changer (pas pendant un chargement, un envoi, ni avec des notes non enregistrées sans confirmation). Rien d'un jeu ne reste affiché pour un autre (dossier choisi, version en ligne, signature) ; un envoi interrompu reste attaché à son jeu. Les confirmations et résultats de publication nomment le jeu. Avec un seul jeu, il est choisi d'office. Page « Fichiers du serveur » : le jeu à nettoyer se choisit de la même façon. -
Page « Publier une version » (permission
releases.publish: propriétaires et administrateurs) : choix dumanifest.jsonproduit par le .bat (ManifestBuilder), contrôle du dossier (mêmes règles que le serveur : chemins sûrs, archive et fichiers présents), version en ligne rappelée (avertissement si même numéro ou version inférieure), puis envoi : manifest, fichiers absents du serveur seulement (petits fichiers par lots, gros par morceaux), archive par morceaux de 4 Mo, chaque fichier vérifié (SHA-256) des deux côtés, et mise en ligne avec le manifest en dernier (historique des notes du serveur conservé). « Interrompre » garde ce qui a été envoyé : « Publier » reprend. Pas de verrouillage pour inactivité pendant l'envoi. Installation sur le VPS :server/deploy/LISEZMOI.md, étape 3 quater. -
Page « Mes appareils » (tout administrateur) : vos PC (clés), avec leur empreinte et leur dernière connexion. « Ajouter un appareil » crée une invitation « nouvel appareil » (code affiché une seule fois) ; sur le nouveau PC, « J'ai une invitation » ; de retour ici, l'appareil en attente s'approuve en saisissant l'empreinte affichée sur le nouveau PC. Personne d'autre ne peut approuver un appareil à votre nom. Révoquer un appareil perdu : propriétaires (sinon, demandez à un propriétaire).
-
Page « Administrateurs » (permission
admins.manage) : inviter (nom, groupe → code à transmettre, affiché une seule fois), approuver le premier appareil d'un invité avec l'empreinte qu'il vous dicte, changer le groupe d'un compte, révoquer un appareil ou un compte, supprimer une invitation. Impossible de changer son propre groupe, de se révoquer, ou de retirer le dernier propriétaire actif ; seuls les groupes dont vous avez toutes les permissions sont proposés. -
Page « Groupes et permissions » (permission
admins.manage) : créer, renommer, décrire et supprimer des groupes d'administrateurs, cocher leurs permissions ; créer des permissions personnalisées (« module.action », pour un module futur) et les supprimer (retirées de tous les groupes). Les permissions intégrées (vérifiées par le code) ne se suppriment pas. Le groupe Propriétaire a toujours toutes les permissions (ni modifiable ni supprimable). On ne modifie pas les permissions de son propre groupe, on n'accorde que des permissions que l'on a soi-même, et un groupe qui a des membres ou des invitations ne se supprime pas. Effet immédiat (sessions ouvertes comprises), requêtes signées, journal d'audit. Mise en place :server/deploy/LISEZMOI.md, étape 3 septies. -
Signature du contenu (phase 7) : chaque version mise en ligne et le catalogue portent la signature de l'administrateur qui les publie (automatique depuis le launcher ; une version envoyée avec WinSCP se signe ensuite depuis la page « Publier une version »). Les launchers ne font confiance qu'aux clés du trousseau (
keyring.json), signé hors ligne par la clé racine du launcher avectools\sign-keyring.batet publié depuis la page Signature (propriétaires), qui montre aussi l'état de chaque contenu. Côté joueur,"keyringUrl"et"contentSigning"("warn"puis"require") danslauncher.json(intégré à l'exe) ; en « require », un manifest non signé, mal signé ou plus ancien que le dernier vu est refusé (le jeu installé reste jouable), et un catalogue refusé est ignoré. Après le retrait d'une clé compromise, relevez"keyringMinSequence"au numéro du nouveau trousseau. Mise en place :server/deploy/LISEZMOI.md, étape 3 quinquies. -
Page « Journal d'audit » (permission
audit.read: propriétaires et administrateurs) : connexions, invitations, approbations, publications, modifications et refus, les plus récents d'abord (par pages de 200). Filtres par période (aujourd'hui, 7 ou 30 derniers jours, ce mois-ci, mois précédent, ou dates « du / au » au format jj/mm/aaaa), catégorie, résultat et texte (nom, appareil, IP, clé…). La période est demandée au serveur (paramètrebefore) et les pages sont chargées jusqu'à son début (5000 entrées au plus) ; l'export CSV reprend toutes les entrées filtrées, période comprise. Le journal se surveille lui-même : chaque consultation (ouverture, « Actualiser », période changée) est inscrite par le serveur (« Journal d'audit consulté » : auteur, appareil, IP, nombre d'entrées lues), et chaque export l'est avant l'écriture du fichier (« Journal d'audit exporté (CSV) » : nombre d'entrées, période, filtres) ; si le serveur ne peut pas l'inscrire, le fichier n'est pas écrit. Catégorie de filtre « Consultations et exports du journal ». Chaque entrée indique l'appareil sous le nom choisi à l'enregistrement de sa clé (« J'ai une invitation »), jamais le nom Windows du PC (colonne « Appareil » de l'export CSV). -
Page « Fichiers du serveur » (permission
files.manage: propriétaires et administrateurs) : contenu du site public (dossiers, tailles, dates, espace libre du disque) et état de chaque fichier : Utilisé (archive, fichier d'une version, exécutable du launcher, image du catalogue), Protégé (.json), Inutilisé (supprimable) ou Non vérifiable. Un fichier inutilisé se supprime après confirmation ; « Nettoyer le dossier objects » supprime les fichiers d'un jeu que la version en ligne n'utilise plus (analyse d'abord). Le serveur relit tous les manifests du site avant chaque suppression et refuse tout fichier encore désigné, ainsi que pendant une publication. Mise en place :server/deploy/LISEZMOI.md, étape 3 sexies. -
Catalogue côté joueur :
"catalogUrl"danslauncher.json(racine, https ; en Release, seule la valeur intégrée à l'exe compte). Lu au démarrage sans le retarder (2,5 s au plus, sinon appliqué au démarrage suivant), mis en cache (fonctionne hors ligne), toute valeur invalide ignorée. Images : PNG/JPEG du même serveur, danscatalog/images/(envoyées depuis la page Jeux sous le nom de leur empreinte SHA-256, vérifiée par le launcher au téléchargement ; ou déposées à la main sous un nouveau nom). Installation sur le VPS :server/deploy/LISEZMOI.md, étape 3 bis. -
Principe : le launcher étant public, la sécurité est assurée par le serveur. Chaque administrateur possède une clé privée (sur son PC, chiffrée) ; le serveur ne connaît que les clés publiques. Connexion par défi signé, sessions courtes, et toute modification signée par la clé (un jeton volé ne permet que de lire). Journal d'audit de chaque action.
-
Groupes (anciennement « rôles ») : propriétaire (tout, dont la gestion des administrateurs ; groupe système), administrateur (contenu, publication, journal d'audit, fichiers du serveur), éditeur (contenu) par défaut ; modifiables et complétables depuis la page « Groupes et permissions ».
-
Ajouter un administrateur : invitation (code à usage unique, 24 h) → la personne enregistre sa clé → un propriétaire approuve en saisissant l'empreinte que la personne lui communique. Un nouveau PC d'un administrateur existant est approuvé par lui-même, depuis un PC déjà enregistré.
| Pour… | Où |
|---|---|
| Installer le serveur sur le VPS, créer le premier propriétaire, récupération | server/deploy/LISEZMOI.md |
| Publier le serveur | tools\publish-server.bat (Linux x64 autonome + empreinte SHA-256) |
| Créer sa clé, tester la connexion, inviter/approuver | Menu d'administration du launcher (pages « Mes appareils », « Administrateurs », « Groupes et permissions ») ; en ligne de commande : tools\admin-key.bat (help pour la liste) |
| Signer le trousseau des clés autorisées à signer le contenu | Page « Signature » › « Exporter la demande… », puis glisser le fichier sur tools\sign-keyring.bat (clé racine, hors ligne ; nouvelles clés signalées, à vérifier de vive voix), puis « Publier le trousseau signé… » |
| Lancer le serveur en local (F5) | Projet GameLauncher.Server, profil Development : http://127.0.0.1:5080/api/ |

