Articles :: Logiciels :: Jeux

Les serveurs de jeu

Les bases pour les interroger

mercredi 8 février 2006 par DBSor

Sommaire

L’univers Windows offre aux joueurs en réseau différents utilitaires permettant de connaître l’état d’un serveur, le nombre de joueurs, la possibilité de l’administrer, tout cela sans lancer le jeu et taper des commandes plus ou moins simples à mémoriser. Dans notre univers, ce type d’utilitaire fait défaut, à croire que les bons joueurs ne programment pas et que les bons codeurs ne jouent pas. N’étant ni l’un ni l’autre, je me suis intéressé à la question et je vous livre ci-dessous le fruit de mes recherches.

1. État de l’art

Contrairement à ce que l’on pourrait croire, quelques utilitaires tournent sur notre plate-forme, mais cela est dû au choix judicieux de faire tourner MacOS sur un noyau UNIX. Les utilitaires disponibles le sont sous forme de code Open Source qu’il faut compiler après avoir installé un compilateur (xcode est gratuit et fournit le nécessaire). Parmi ces utilitaires, citons :
-  vrcon, très simple à installer, permet d’effectuer les opérations de base sur Quake 3, Call of Duty (CoD), Unreal Tournament (UT), etc.
-  qstat, beaucoup plus complet mais aussi plus lourd à installer et à utiliser
-  XQF, interface graphique de qstat sous X11, déjà plus délicat à mettre en place (fink est fortement recommandé pour installer certaines bibliothèques)
-  Utilitaires PHP : signalons qu’il existe tout un tas de scripts php permettant d’interroger les serveurs de jeu

2. La commande de base : statut du serveur

La commande de base d’interrogation est la commande de statut, elle ne nécessite aucun privilège et permet de récupérer un certain nombre d’informations à partir de l’ip et du port du serveur, comme la version du jeu, le nombre de joueurs connectés, leurs noms, leurs scores et leurs pings, le nombre maximum de joueurs possible, l’administrateur du serveur, etc.

Chaque jeu a évidemment une syntaxe particulière pour cette commande, celle-ci se trouve généralement assez facilement sur internet, citons notamment un site qui fournit une mine d’informations utiles, celui de KQUERY et notamment sa partie consacrée au développement.

M’étant plus particulièrement intéressé à Call of Duty, je fournirai des exemples pour ce jeu, sachez que les commande de Quake sont identiques à peu de choses près.

Voici donc un programme simple en C qu’il suffit de copier/coller dans un projet de type "Standard Tool" dans xcode pour tester.


#include <stdio.h>
#include <string.h>

// fonction socket
#include <sys/types.h>
#include <sys/socket.h>
// definition sockaddr_in
#include <netinet/in.h>


int main (int argc, const char * argv[]) {

        char monIp[16]={"xxx.xxx.xxx.xxx"};        // ip du serveur
        char monPort[6]={"xxxxx"};                        // port du serveur

        char command[512];
        char buffer[2048];
       
        int maSocket;
        int tailleRetour;
       
        struct sockaddr_in sain;
       
        printf("Début du programme\n");
       
        printf("Création socket...");
        maSocket = socket(AF_INET,SOCK_DGRAM,0);
        if(maSocket == -1)
        {
                printf("échec.\n");
                return 0;
        }
        else
                printf("ok\n");

       
        printf("Connexion à %s:%s ...",monIp,monPort);
        sain.sin_family = AF_INET;
        sain.sin_port = htons(atoi(monPort));
        sain.sin_addr.s_addr = inet_addr(monIp);

        if(connect(maSocket, (struct sockaddr *) &sain, sizeof(sain)) == -1)
        {
                printf("échec.\n");
                close(maSocket);
                return 0;
        }
        printf("... ok\n");


        printf("Envoi de la commande:");
        strcpy(command,"\xFF\xFF\xFF\xFFgetstatus"); // ligne à modifier
        printf("%s \n",command);
        if(send(maSocket, command, strlen(command), 0) == -1)
        {
                printf("échec.\n");
                close(maSocket);
                return 0;
        }
       
        printf("Réception: ");

        memset(buffer,'\0',sizeof(buffer));
        tailleRetour = recv(maSocket,buffer,sizeof(buffer),0);
        if (tailleRetour == -1)
        {
                printf("échec.\n");
                close(maSocket);
                return 0;
        }
        printf("%i octets\n",tailleRetour);
        printf("Réponse: %s\n",buffer);

   close(maSocket);
   return 0;
}

Ce code simple montre une manière d’établir une liaison avec le serveur (socket) et de l’interroger avec le protocole udp, utilisé pour la plupart des jeux en ligne (SOCK_DGRAM). Contrairement au ftp, ce protocole n’est pas sécurisé, et un problème pouvant se poser est l’ordre de réception des paquets (datagrammes), le premier reçu n’étant pas forcément le premier envoyé. Dans l’exemple ci-dessus, toute l’information tient normalement dans un seul paquet udp.

Voici un exemple de retour :

De nombreuses informations sont disponibles, tout d’abord un accusé de bonne réception (statusResponse), suivi d’un certain nombre de champs sous la forme "\nom du champ\valeur du champ". Parmi ces informations se trouvent le type de jeu (g_gametype), la carte en cours (mapname), la version du jeu sur le serveur (shortversion) ou encore le nombre maximum de joueurs autorisés sur le serveur (sv_maxclients), etc.

Vient ensuite la liste des joueurs présents sur le serveur sous la forme "score ping nom". Ce dernier champ, comme le nom du serveur (sv_hostname), peuvent comporter des codes de couleur sous la forme ^n, n variant de 0 à 9 et indiquant la couleur des caractères qui suivent. A titre informatif, ces codes sont :

  • ^0 = Noir
  • ^1 = Rouge
  • ^2 = Vert
  • ^3 = Jaune
  • ^4 = Bleu
  • ^5 = Bleu clair
  • ^6 = Violet
  • ^7 = Blanc
  • ^8 = Orange
  • ^9 = Gris

3. Les commandes RCON

Si vous êtes administrateur d’un serveur de jeu, vous pouvez entrer un certain nombre de commandes par la "console". Celles de Call of Duty permettent par exemple de redémarrer une carte, changer de carte et de type de jeu, mettre un mot de passe ou encore "kicker" un joueur indésirable.

Toujours dans Call of Duty, il suffit de remplacer la commande de statut dans le code ci-dessus par une commande du type :


strcpy(command,"\xFF\xFF\xFF\xFFrcon mot_de_passe commande");

La syntaxe des commandes se trouve sur les forums de jeu généralement, ou en explorant le code source de browsers existants.

En voici quelque unes pour CoD :

-  map_restart pour redémarrer la carte
-  map_rotate pour passer à la carte suivante
-  map nom_de_la_carte pour mettre la carte spécifiée
-  g_gametype gametype pour changer le type de jeu
-  say blabla pour dire blabla à tout le monde
-  kick bill_gates pour exclure le joueur qui s’appelle bill_gates, il n’est pas nécessaire d’inclure les codes de couleur dans le nom du joueur

A noter que certaines commandes ne peuvent s’enchaîner et qu’il faut prévoir un petit délai entre elles pour que les deux soit prises en compte, comme par exemple g_gametype et map_restart.

Enfin, il est possible de récupérer des informations sur le serveur, comme par exemple les cartes disponibles ou les fichiers de configuration (*.cfg) en utilisant la commande fdir. Le retour de cette commande peut ne pas tenir sur un seul paquet udp, il faut donc tester un code de fin (comme par exemple le nombre de fichiers renvoyés sous la forme "xx files listed"). De plus, le second paquet peut arriver avant le premier sur certaines configurations, je vous laisse imaginer la gymnastique pour tout remettre dans le bon sens.

4. Les master servers

Une autre particularité des jeux en ligne est la présence de "master servers", serveurs qui regroupent les adresses des serveurs en ligne. Je ne vous parlerai pas ici de ceux de type "gamespy" car le protocole utilisé n’est officiellement pas "ouvert" même si il est relativement aisé de le trouver sur des sites spécialisés.

Pour les serveurs maîtres officiels des jeux de type Quake III, CoD, etc, la commande à utiliser pour les interroger est :


strcpy(command,"\xFF\xFF\xFF\xFFgetservers protocol empty full");

La variable protocol est un entier qui dépend de la version du jeu, il correspond au champ "protocol" de la commande getstatus. Dans le cas de Call of Duty, il vaut 6 pour la version 1.5 du jeu, 22 pour son extension United Offensive en version 1.51, et 115 pour Call of Duty 2 en version 1.0, uniquement disponible sous Windows pour le moment (vivement le moi de mai !)

Les paramètres empty et full sont optionnels et permettent de récupérer les serveurs vides et ceux qui sont pleins. Si ces options fonctionnent très bien sur les serveurs de Quake III, elles sont totalement ignorées sur ceux de Call of Duty et son extension.

En réponse à cette commande, le serveur maître renvoie tout un tas de paquets udp qui comprennent les ip et port des serveurs disponibles, sous la forme "ip :port ;". La fin de la réponse se caractérise par un code de type "EOF", un essai de réception permet de vérifier ce code de fin du serveur en fonction du jeu.

5. Exemple de Call of Duty : iClanASC

Parallèlement à ces recherches, je me suis mis à la programmation de Cocoa afin de réaliser un petit programme gratuit adapté à Call of Duty et son extension. Ce programme dénommé iClanASC exploite un certain nombre de commandes expliquées ci-dessus. Destiné à l’origine à simplifier la vie de certains administrateurs (un peu fainéants) des serveurs du iClan, j’ai peu à peu étoffé le programme et décidé de le diffuser librement.

Pour ceux qui craindraient de se lancer dans ce type de développement, sachez que des connaissances de base du langage C suffisent pour créer ce type de logiciel tant la documentation Apple est abondante pour les débutants, les outils (xcode et interface builder) sont simples à utiliser et les participants aux différents fora de programmation sur mac ne sont pas avares de conseils. Je conseillerais tout de même aux débutants le lecture de Cocoa par la pratique, de Aaron Hillegass aux éditions Eyrolles , un très bon livre pour débuter.

Je vous livre ci-dessous quelques captures d’écran de ce programme pour illustrer les possibilités :

-  Fenêtre principale

Cette fenêtre présente les serveurs placés dans la liste principale et les joueurs présents sur le serveur sélectionné ainsi que des informations sur ce serveur (carte en cours, système "anti-cheat" de type punkbuster,...) La fenêtre des joueurs correspond à peu de chose près à l’exemple fourni plus haut.

Les boutons "+","modify" et "-" servent à ajouter, modifier ou supprimer des serveurs de la liste principale. Les boutons "refresh" servent à ... rafraîchir les informations sur le(s) serveur(s).

Des informations plus détaillées sont obtenus en cliquant sur le (i) :

Dans le cas d’un serveur pour lequel le mot de passe est connu, le panneau suivant s’affiche afin d’administrer le serveur.

A l’aide de ce panneau, il est possible d’effectuer les opérations de base (les noms des boutons sont suffisamment explicites).

Il est également possible de prévoir une "rotation de cartes" temporaire pour passer une bonne soirée entre amis sans perturber la rotation habituelle du serveur à l’aide d’un interface graphique :

Enfin, il est possible en interrogeant le "master server" puis tous les serveurs individuellement de rechercher un joueur ou un serveur, comme indiqué ci dessous :

Cette fonction est très pratique pour retrouver un ami en jeu, ou les membres d’un clan. D’un point de vue programmation, je conseille l’utilisation du multitâche (threads) pour accélérer l’interrogation des serveurs. A titre d’information, il fallait environ 4 minutes pour interroger 4000 serveurs avec un seul "thread", ce temps est maintenant situé entre 10 et 30 secondes suivant la bande passante disponible et la configuration réseau de l’utilisateur.

6. Conclusion

Ce petit article vous fournit les principales informations pour écrire un petit programme adapté à votre jeu préféré. Personnellement, avec quelques connaissances de base en C, il ne m’a fallu que quelques soirées et parties de week-end pour sortir un première version alpha utilisable.

Il aura fallu environ 8 mois pour sortir une première béta publique en y consacrant un peu de temps de loisirs. Le seul problème, c’est que la programmation est un exercice très prenant, le temps consacré au jeu diminue et le niveau baisse...

Si vous voulez vous faire une idée des possibilités, vous pouvez télécharger iClanASC en version béta au moment de la rédaction de cet article à cette adresse. Merci de lire les avertissements avant de télécharger.

 

11-03-2006 12:16:53, par DBSor

Juste pour signaler qu'il existe un autre soft qui s'appelle Only Mortal et qui se trouve sur le site d'Apple/MacOS X/Downloads/Games/Utilities.
C'est un browser de serveurs de jeux, pour JK2, Quake 1,2 & 3, QW, RtCW, SoF2 et UT.

Recherche

A propos — Site collaboratif édité sous licence GNU FDL [pourquoi ?] — © 2004-08 — Mentions légalesContact
Syndication RSS — Powered by SPIPstockbanddonné


Contenu édité sous licence GNU FDL sans sections invariantes
© MacTouch 2004-08 — Powered by SPIP
http://www.mactouch.com/.