Ayant été le seul programmeur chez Tactical Soft à part le patron, cet emploi m'a permis d'enrichir énormément mes connaissances car j'ai du toucher et m'auto-former à nombre de domaines différents.
A.R.S.E.N.A.L. Extended Power pour Windows (95 à XP) et Linux est un jeu de stratégie style Alerte rouge. Ca c'est pour l'idée de base, car la ressemblance s'arrête là. ARSENAL est concu sur le principe du multi-joueurs. Ce n'est pas le principe du joueur contre l'ordinateur, mais le joueur contre plusieurs adversaires (ou alliés) qui peuvent être éventuellement des IA. ARSENAL vise à créer une communauté virtuelle en ligne. Divers moyens de communications et d'échanges au sein de cette communauté sont les highscore mondiaux, le forum, le partage des cartes crées par les utilisateurs via le serveur, les parties en réseau local ou via Internet... De plus, autre différence: chaque joueur évolue et pas au cours d'une simple partie, mais pendant toute sa vie; en plus d'un grade en fonction de ses performances, selon la facon dont le joueur traite ses ennemis ou alliés il obtient une réputation qui peut aller de traitre à héros... Cette réputation est très importante, car les autres joueurs (et surtout les IA) en tiennent compte avant d'accepter une alliance.
Ca c'était pour la présentation du jeu et je vais maintenant vous présenter mon travail. J'ai eu à travailler sur 4 parties différentes du projet:
- Le client qui gère la license (identifie au serveur l'unique machine enregistrée pour la license, transfère la license sur une nouvelle machine, met-à-jour le jeu ou télécharge des add-on, lance ce dernier en version complète ou démo selon les cas...)
- Le jeu en lui-même.
- Une interface de monitoring à distance temps réel du serveur.
- Le serveur à tout faire qui consiste en un programme C++ tournant 24h/24 sur une machine Linux (paiement, licenses, scores, mise-à-jour, add-on, cartes utilisateurs, forum...)
Dans cette section contrairement aux autres, vous ne verrez que peu de détails techniques surtout concernant le serveur. En effet, je dois faire attention à ne pas rendre publique une information qui pourrait servir à un éventuel piratage. Vous ne verrez pas non plus de screenshots. Pourquoi? Dans la majorité des cas, j'ai surtout travaillé sur des algorithmes et des choses cachées. L'intérêt des screenshots serait assez limité du style "regardez le jeu affiche sous Linux", "regardez le jeu se connecte au serveur" ou encore "regardez le jeu joue des MP3 ou du MIDI" (sans blague?). Toutefois, la démo est fournie en bas de page et vous pourrez donc essayer (la totalité des fonctionnalités décrites ne sera accessible que si vous achetez le jeu).
Le client:
- Le client consiste en une interface MFC multi-langues (3 langues actuellement: anglais, francais et allemand) destinée à gérer la license du joueur. Après avoir joué la démo, le joueur a juste à cliquer sur le bouton "Acheter". Le client identifie alors sa machine de facon unique auprès du serveur. Le joueur se voit alors proposer le choix de payer directement en ligne par carte de crédit et de télécharger sa license tout-de-suite (conversions des différentes monnaies du monde affichées), ou alors d'imprimer un formulaire à envoyer par voie postale avec son chèque. Après réception, il recevra par email des instructions pour télécharger sa license.
- Une fois la license téléchargée, le client rappelle à l'utilisateur de faire des sauvegardes de sa license à intervalles réguliers. Ce dernier peut alors jouer la version complète du jeu et avoir accès aux autres fonctions fournies par l'interface client: enregistrer son score dans la liste des meilleurs scores au monde, écrire des messages sur le forum et surtout télécharger les mises-à-jour et add-on du jeu.
- La license est accordée pour l'utilisation sur 1 machine. Si l'interface client détecte qu'elle a été lancée sur un ordinateur différent, elle affiche un message offrant à l'utilisateur le choix de transférer sa license sur son nouvel ordinateur (et il n'a plus le droit de jouer avec l'autre), ou d'acheter une nouvelle license. Si après un transfert l'utilisateur continue de jouer sur son ancienne machine, le serveur sanctionne alors ce dernier en suspendant temporairement sa license, le privant ainsi de tous les services offerts aux utilisateurs enregistrés: il retombe avec une version démo. Un message est affiché par le client et informe l'utilisateur qu'il a violé la license, lui donnant même tous les détails (license enregistrée pour tel ordi à telle date, utilisée sur tel autre ordi à telle date...) et l'invitant poliment à se mettre dans la légalité pour que sa license soit réactivée. J'ai même réalisé du code pour prendre une capture de l'écran de l'ordinateur de l'utilisateur lors de la violation de la licence, compresser l'image en JPEG et ainsi l'envoyer discrètement par Internet. Toutefois ce code n'est pas utilisé car à de très rares exceptions près, les gens qui se font avoir ne créent pas de problèmes et la très grande majorité d'entre eux achètent alors une 2ème license pour l'ordinateur violateur, ce qui leur est demandé afin de réactiver la license originelle.
Grâce à cet ingénieux système innovateur de protection (Microsoft semble d'ailleurs avoir choisi un système de protection/gestion de licenses similaire pour son dernier système d'exploitation Windows XP sous le nom de TCPA/Palladium), nous évitons que la même license serve sur tous les ordinateurs de la maison ou chez tous les ordis des copains, scénarios habituels chez les adolescents et parfois les plus âgés.
Le jeu:
Concernant le jeu, j'ai travaillé sur quelques modules, le jeu en lui-même étant déjà réalisé quand je suis arrivé.
- J'ai réalisé un player MIDI pour le jeu version WINDOWS. Il lit aussi les fichiers RMI. Pour cela, je me suis inspiré du lecteur MIDI fourni avec le MSDN. J'y ai d'ailleurs corrigé un bug: les dernières notes du fichier n'étaient jamais jouées car le test d'arrêt était mal fait.
- J'ai réalisé l'interface bas niveau qui permettent de jouer le son pour le jeu version Linux. Il s'agit simplement après quelques initialisations d'érire du WAVE dans le fichier périphérique /dev/snd. Comme pour Windows aussi on écrit du WAVE (mais en mémoire), c'est donc juste 1 ligne qui change: celle qui appelle la fonction pour jouer le son déjà mixé sous Windows ou sous Linux.
- J'ai fait la même chose pour l'interface d'affichage vidéo sous Linux. Une interface avait déjà été faite par un autre programmeur et utilisait les librairies SDL supposées être des librairies d'accès direct au matériel. Sur le machine testée, on avait 320 images par seconde sous Windows et seulement 40 sous Linux... Il semblait donc que cette librairie ne se configurait pas toujours automatiquement toute seule... De plus, elle n'était pas installée par défaut sous toutes les versions Linux, et nous voulions quelque chose qui marche tout seul sous Linux comme sous Windows, sans besoin de configurer ou d'installer quoi que ce soit afin de viser tous les utilisateurs Linux, des débutants aux plus érudits. Il fallait utiliser les fonctions le plus bas niveau possibles afin qu'elles existent sur tous les systèmes et afin d'accéder directement au matériel vidéo et donc avoir l'affichage le plus rapide possible. J'ai utilisé la librairie censée être utilisé par X11 (le moteur graphique de Linux sur toutes les machines Intel x86): la librairie DGA en mode 256 couleurs. Il suffisait de lui donner une palette des 256 couleurs, et d'avoir ensuite un tableau de leurs codes (image actuelle) à porté de main. J'ai obtenu un affichage à 300 images par seconde (contre 320 pour Windows) ce qui était tout-à-fait acceptable contre 40 images par seconde. Les différences peuvent être dues aux différences de drivers ou aux ressources utilisé ou réservées par le système.
- Enfin, j'ai réalisé l'interface Linux gérant les entrées clavier et souris, toujours en utilisant la librairie DGA de X11.
- J'ai par la suite eu à réaliser un lecteur de MP3 multi platte-formes (Windows et Linux) pour le jeu, tout comme j'avais déjà fait un lecteur MIDI. Je me suis servi des "gros" codes de décodage fournis sur www.mp3-tech.org (que j'aurais certainement mis des mois à reproduire sinon). Toutefois, j'ai quand-même eu à gérer bien des choses de plus haut niveau, comme sauter les tag d'information de début ou fin de fichier, identifier le format du mp3, fournir aux algorithmes de décodage les options du mp3 récupérables dans chaque frame (CRC, padding...). Le lecteur a été testé avec de nombreux cas: MPEG-1, MPEG-2, MPEG-2.5 le tout en layer 3 (du nom de MP3), mp3 avec tags, mp3 à bitrate variable (VBR), et même mp3 dans un fichier wave. J'ai utilisé du code à 100% aux normes ANSI, ce qui fait qu'il a compilé et fonctionné sous Windows et Linux.
- Pour le son il subsistait un problème: seuls les sons au format sonore dans lequel était lancé le jeu étaient joué correctement. Bref la majorité des mp3 trouvables sur Internet étaient joués au ralenti. (le jeu était en 22kHz Mono) J'ai donc changé le mode du jeu (non changeable par l'utilisateur) en 44kHz stéréo. J'ai ensuite réalisé un algorithme de conversion automatique mono vers stéréo et 22kHz vers 44kHz (+lissage). Le jeu a ainsi pu fonctionner sans toucher à ses échantillons sonores originaux, et en même temps avec les tous derniers mp3 que l'utilisateur pouvait récupérer sur Internet.
- Dernière petite chose à propos du son: récupérer les informations à propos des titre et auteur des mp3 pour les afficher. J'ai donc eu à gérer les tags de type ID3v1, ID3v2 (versions 2 à 4), et Brava, avec leurs frames et padding éventuels le tout en me documentant principalement sur www.id3.org. Là aussi tous les cas ont été testés.
- Et enfin dernier travail sur le jeu: vous vous souvenez que j'avais dit que le but pour Linux était que ca marche tout seul partout? Et bien sous linux un binaire (exécutable) nécessite des librairies dynamiques. Mais, il n'y a pas de compatibilité ascendante ou descendante entre leurs différentes versions... Et contrairement à windows, où on peut avoir plusieurs dll dont seul la fin du nom (version) est différente, plusieurs versions de la même librairie ne peuvent pas coexister sur le système. Je m'explique: Par exemple, supposons que le jeu Linux ait besoin de la librairie xf86dga pour les extensions DGA. (j'aurais pu aussi citer x11, xf86vmode, zlib...) Lors de la compilation à la phase d'édition de liens, l'exécutable est marqué comme ayant besoin de la librairie DGA trouvé sur le système par exemple "XF86DGA-1.1". Si on essaye ensuite de lancer le jeu sur un système Linux avec XF86DGA-1.0 ou XF86DGA-2.0, ca ne marchera pas... Ca marchera sur les seules systèmes avec XF86DGA-1.1. La solution que j'ai trouvée est de compiler le binaire en statique: les librairies sont alors incluses dans l'exécutable et ca marche sur tous les systèmes Linux. Enfin, dernière chose sur cette compilation: il faut savoir que les nouvelles versions des librairies ajoutent souvent de nouvelles fonctions et sont donc plus grosses. Par exemple, DGA2 ajoute 10Mo au fichier alors que je n'utilise que des fonctions DGA1. J'ai donc fait des recherches pour compiler la version Linux statique du jeu avec les librairies les plus "minimales" possibles pour que la taille finale du fichier soit raisonnable pour un téléchargement Internet.
- Comme je le disais ci-dessus, je suis donc arrivé en cours de route sur ce projet, mais il y a toutefois une idée qui vient de moi: fort de mon travail déjà effectué avec Pikastle 3D la version en ligne, j'ai moi-même proposé à mon employeur que puisque nous avions déjà un éditeur de cartes dans le jeu, nous pourrions implémenter un système de partage des cartes des utilisateurs. Si la carte créee par un utilisateur est bonne, elle est publiée sur le serveur et disponible en téléchargement pour tous les autres utilisateurs. L'intérêt moral de cette pratique est que notre communauté virtuelle peut alors évoluer toute seule: les utilisateurs fournissent sans arrêt de nouvelles cartes pour les autres, sans besoin d'aucune intervention de Tactical Soft (pas besoin d'engager de facon permanente un graphiste pour faire des cartes). Un intérêt plus matériel est que nous avons ainsi plein de "graphistes" qui nous créent des cartes totalement gratuitement, et par là-même enrichissent le patrimoine virtuel du jeu et attirent ainsi de nouveaux clients. Que demander de mieux? ;) Niveau contrôle, là aussi c'est un système d'auto-contrôle qui a été choisi: les joueurs peuvent voter afin de donner une appréciation des cartes disponibles sur le serveur. Grâce aux votes, l'utilisateur cherchant une carte se voit présenter les meilleures cartes en premier, et les pires en dernier.
- Ca n'a pas de rapport avec la programmation, mais j'ai aussi fait la relecture et la correction des textes de toutes les campagnes pour la version allemande du jeu, et j'ai doublé quelques voix.
Monitoring du serveur:
J'ai donc réalisé une application de monitoring du serveur en temps réel. Cette application permet de:
- afficher en direct les noms des utilisateurs connectés au serveur et leur adresse IP ainsi que ce qu'ils étaient en train de faire (score, forum, transfert de fichier, achat, paiement...)
- faire un backup des fichiers du serveur (fichiers d'informations sur chaque utilisateur leur permettant ou pas d'utiliser les services du serveur): il s'agit d'un backup incrémental et donc très rapide malgré la quantité énorme d'informations gérées (les historiques comprenant toutes les actions effectuées par plus de 10000 clients).
- afficher des informations sur un utilisateur ainsi que son historique (liste chronologique de toutes ses actions sur le serveur): c'est un simple affichage formatté des fichiers de l'utilisateur récupéré par le backup
- rechercher des utilisateurs selon des critères (nom, pays, license activée...): il s'agit d'une recherche sur les fichiers locaux récupérés par le backup.
- et enfin, afficher la liste complète des utilisateurs et permettre de la trier par différents critères (date, nom, ville, pays...): j'ai réalisé cette fonctionnalité alors que nous avions déjà plus de 10000 clients enregistrés. J'ai donc du frapper fort dès le début en implémentant une version itérative du meilleur algorithme de tri existant à ce jour: le tri par tas. Le tri alphanumérique sur plus de 10000 clients ne dure que 2 secondes sur une machine à 400MHz. De plus cette algorithme a une complexité logarithmique: plus il y a d'informations, moins l'algorithme prend de temps supplémentaire. C'est le meilleur type d'algorithme existant. Par exemple, le jour où il y aura 20000 clients, le tri prendra non pas 4 secondes, mais moins de 4 secondes.
Le serveur:
Sur le serveur j'ai eu à réaliser les pendants des diverses fonctionnalités citées ci-dessus, bref le code qui répond au client dans le cadre de l'achat, de la license, du téléchargement de fichiers, de l'enregistrement des scores, du backup incrémental... Dans ce cadre, j'ai également amélioré le format et la gestion des paquets ARSENAL circulant sur le réseau, en effet cette gestion comportait quelques bugs à mon arrivée, des paquets pouvant être mal lus ou oubliés dans certains cas.
Je n'ai donc pas grand chose à redire là-dessus. Le but étant d'avoir un serveur C++ tournant 24h/24, la programmation se devait d'être extrêmement propre. Outre l'absence de bugs, il fallait éviter les fuites de mémoire, cause principale des plantages des serveurs tournant en permanence. Divers tests ont été effectués pour s'assurer de l'absence de telles fuites. Depuis bientôt 1 an et demie, ce serveur tourne en permanence 24h/24 et sans aucun problème ou plantage logiciel (je ne peux rien contre les pannes de courant...). Par souci de fiabilité un 2ème processus serveur "veille" sur la même machine sur un autre port. Cela permet aux clients de continuer d'accéder aux services ARSENAL si jamais le programme serveur principal est indisponible. Ca évite donc que tous les services soient indisponibles le temps de relancer le serveur principal. Ce serait donc utile en cas de plantage du programme serveur principal (même si ca n'arrive pas). Par contre, c'est très utile lors de la recompilation du serveur (mises-à-jour). On recompile, on tue et relance le serveur principal (si un client arrive en même temps, il se connecte de facon totalement transparente au serveur secondaire), et ensuite on tue puis relance le serveur secondaire.
En conclusion, je peux dire que cette expérience difficile m'a beaucoup appris dans les domaines du multimédia et des réseaux, et surtout m'a appris à être totalement autonome, recherchant moi-même les documents ou informations dont j'avais besoin.
A.R.S.E.N.A.L Extended Power 2.9, version démo anglais/francais/allemand (version Locale / CD du site)
(version du 24 octobre 2003, qui comprend donc mon dernier travail sur les mp3. A l'heure où je publie cette page, c'est toujours la dernière version, mais pour voir si il en existe des nouvelles, allez sur: www.tacticalsoft.com)
|