Dans cet article, je vais vous expliquer comment j'ai créé un système de mise à jour automatique pour un jeu client en ligne. Lien vers la source (Delphi) à la fin de l'article. En fait, j'ai implémenté une telle fonctionnalité dans mes deux jeux, et si la première crêpe est sortie un peu bosselée (dans le jeu Spectromancer), alors la deuxième implémentation s'est avérée très pratique et efficace. Ceci est mon premier article sur Habré, alors ne frappez pas fort, mais signalez plutôt les défauts dans les commentaires :)
Algorithme de mise à jour du jeu
- Vérification de la version pour la mise à jour.
- Téléchargez la liste des fichiers de la version actuelle.
- Téléchargement de fichiers nouveaux ou modifiés dans un dossier temporaire.
- Installer la mise à jour - amener les fichiers du client installé conformément à la liste.
- Démarrage d'un client mis à jour.
Vérification de version
Tout d'abord, lors du démarrage, le client demande au serveur le numéro de la version actuelle (X) et le numéro du minimum autorisé sans mise à jour (Y). Si la version du client n'est pas inférieure à Y, une mise à jour n'est pas requise, sinon le client démarre l'utilitaire de mise à jour "
GetNewVersion.exe X " et s'arrête lui-même.
Comme vous pouvez le voir, le numéro de version est transmis par le paramètre - cela vous permet de mettre à jour le jeu vers n'importe quelle version disponible sur le serveur, et même de le baisser. Si le paramètre n'est pas transmis, l'utilitaire demandera lui-même le numéro de version actuel au serveur. Le numéro de version n'est qu'un entier, le schéma de numérotation peut être n'importe lequel, par exemple, ma version 1.12 correspond au numéro 1120.
La réponse du serveur ne vient pas instantanément, et avant de la recevoir, nous ne pouvons pas créer la fenêtre de jeu, car vous devrez peut-être la fermer immédiatement, et un scintillement incompréhensible sur l'écran n'est pas du tout ce dont nous avons besoin. Le délai de réponse devrait prendre quelque chose, et le client est en train de charger / déballer les fichiers JPEG les plus lourds. Vous ne pouvez pas attendre trop longtemps non plus: le joueur a lancé le jeu - mais rien ne se passe à l'écran, un gâchis. Par conséquent, si dans un délai de 1,0 sec. la réponse du serveur n'est pas arrivée - le chargement du jeu se poursuit de la manière habituelle. Ce n'est pas un gros problème: dès que le joueur essaie de se connecter au serveur, il recevra un message sur la nécessité de mettre à jour le client, ou que le serveur n'est pas disponible.
Télécharger la liste des fichiers
Connaissant le numéro de version, l'utilitaire de mise à jour télécharge la liste des fichiers dans:
[base_ur]>/[]/filelist
Ceci est juste une liste de fichiers CSV avec des sommes de contrôle, ainsi que des tailles compressées et non compressées, chaque ligne ressemble à ceci:
18*Priest.tga;1053151921D9;91719;107372
Ici, «18 *» signifie que 18 caractères dans le nom de fichier sont identiques au fichier précédent. Étant donné que les fichiers sont généralement classés par ordre alphabétique et que les chemins d'accès peuvent être longs, cela économise considérablement la taille du fichier de liste. Pour un serveur Web sur lequel la compression n'est pas activée, cela signifie que le fichier sera téléchargé plus rapidement et que la mise à jour commencera plus tôt.
Télécharger des fichiers nouveaux ou modifiés
Nous ne savons pas quel âge a le client du jeu, peut-être que certains fichiers ont été modifiés ou supprimés manuellement. Nous ne voulons pas trop télécharger, donc, après avoir reçu la liste des fichiers, l'utilitaire commence à les vérifier pour les mises à jour: si le fichier n'est pas dans le dossier du jeu ou si sa somme de contrôle est différente, le fichier est ajouté à la file d'attente de téléchargement. Dans le même temps, pas plus de 2 fichiers peuvent être chargés - c'est assez pour que d'une part le téléchargement ne ralentisse pas, mais d'autre part, il se fait séquentiellement.

Un sujet spécial est l'affichage des progrès. Jusqu'à ce que la liste entière ait été traitée, nous ne savons pas exactement combien de fichiers à télécharger et quelle taille ils sont. Cependant, dès que le premier fichier est téléchargé, nous pouvons déjà afficher certaines informations. En fait, la progression affiche la file d'attente de téléchargement: combien à télécharger et combien a déjà été téléchargé.
Les fichiers téléchargés sont immédiatement décompressés et enregistrés dans un dossier temporaire, j'utilise la bibliothèque
zlib
pour la compression.
Une fois la liste complète des fichiers traitée et tous les téléchargements terminés, l'utilitaire vérifie la présence du fichier
changes.txt
et, s'il existe, l'affiche. L'utilisateur est invité à démarrer la procédure de mise à jour. Avant de cliquer sur le bouton "Mettre à jour", aucune modification n'a encore été apportée au dossier du jeu, vous pouvez donc vous désinscrire sans aucun problème.
Soit dit en passant, si l'utilisateur interrompt le téléchargement ou refuse d'installer, la prochaine fois il n'aura pas à télécharger à nouveau tous les fichiers: avant de télécharger le fichier suivant, l'utilitaire vérifie sa présence dans le dossier temporaire et si la somme de contrôle correspond, le téléchargement est considéré comme réussi.

Mais lorsque vous cliquez sur «Mettre à jour», l'utilitaire lance un autre utilitaire - «
InstallUpdate.exe », et il s'arrête automatiquement.
Installer la mise à jour
Pourquoi ai-je besoin d'un autre utilitaire? C'est simple: pour mettre à jour les fichiers du jeu, vous devez exécuter avec les droits d'administrateur. Mais pour télécharger la mise à jour, au contraire, c'est contre-indiqué. Parce que, à moins que vous ne soyez un heureux propriétaire d'un certificat de signature de code EV, le démarrage du processus avec des droits d'administrateur affichera la fenêtre UAC. Et si, au démarrage du jeu, au lieu de l'interface habituelle, le joueur voit ceci:

... alors c'est au moins une raison de se méfier, voire d'abandonner complètement le lancement. Autre chose, avec le consentement manuel pour installer la mise à jour - dans ce contexte, la fenêtre UAC est perçue normalement. Malheureusement, un processus dans Windows ne peut pas élever ses droits lors de l'exécution - cette propriété n'a pas été modifiée depuis le lancement. Par conséquent, j'utilise deux fichiers distincts. En fait,
GetNewVersion.exe
et
InstallUpdate.exe
sont le même utilitaire, les fichiers sont identiques. Et l'action est déterminée par les paramètres transmis et le nom du fichier exécutable.
Ainsi, en cours de lancement, InstallUpdate copie les fichiers du client de jeu du dossier temporaire dans le dossier du jeu, puis lance le client mis à jour et se termine. Dans ce cas, le fichier
GetNewVersion.exe
peut également être mis à jour.
Toutes les actions, ainsi que les erreurs qui se produisent, sont enregistrées en détail dans le journal, ce qui est très utile pour le débogage.
Le processus de préparation d'une nouvelle version
Nous avons examiné le schéma d'opération de mise à jour du point de vue du client du jeu, mais comment le faire fonctionner? Pour préparer de nouvelles versions, j'ai écrit un autre utilitaire -
CompressBuild . Il analyse récursivement un dossier, compresse les fichiers à l'aide de la méthode Deflate et écrit des informations à leur sujet dans la liste des fichiers - liste de
filelist
. Après la compression, le symbole "_" est ajouté au nom du fichier. Les fichiers compressés ne sont pas compressés à nouveau, par conséquent, si nécessaire, seuls les fichiers individuels peuvent être mis à jour dans le dossier de génération, CompressBuild les mettra uniquement à jour.
Certains fichiers du client de jeu changent pendant le fonctionnement, par exemple, contiennent des paramètres. Ces fichiers doivent être ignorés, l'utilitaire prend les modèles appropriés du fichier d'exclusion. Autrement dit, ces fichiers n'entrent tout simplement pas dans la
filelist
des
filelist
et ne gâchent pas le client lors de la mise à jour.
Ainsi, pour préparer une nouvelle construction, j'ai besoin:
1. Copiez le dossier
\master
dans
\[_]
2. Exécutez
CompressBuild , qui y regroupera les fichiers et en fera une liste.
3. Téléchargez le tout sur le site Web du jeu.
4. Modifiez sur le serveur de jeu le numéro de la version actuelle au numéro que vous venez de télécharger. Voila!
Désormais, lors de la mise à jour, les utilisateurs recevront une nouvelle version.
Eh bien, les dossiers avec d'anciennes versions sur le serveur peuvent être supprimés afin de ne pas prendre de place.
Conclusion
Bien sûr, mon système de mise à jour n'est pas parfait et non sans défauts. Par exemple, si un fichier a été supprimé dans le client, il restera avec les joueurs. Si le fichier a été renommé, il sera téléchargé comme nouveau et l'ancienne instance ne sera pas supprimée. Vous pouvez, bien sûr, affiner l'utilitaire de mise à jour en ajoutant des commandes pour supprimer / renommer des fichiers dans la liste des fichiers, mais en général, ces problèmes ne sont pas pertinents pour mon jeu, donc je n'ai pas pris la peine.
Eh bien, vous pouvez obtenir la source ici:
astralheroes.com/files/UpdaterSrc.zip(compilé dans Delphi-2006 / Turbo Delphi, je ne peux pas me porter garant pour d'autres compilateurs).