~knarf
Suite à l’absence totale de documentation sur internet à ce sujet, j’ai télécharger le code sources de différents clients libres (gtetrinet et tetrinet-console) pour les étudier.
Ce document présente donc le protocole TetriNET. Il se veut suffisament exaustif pour pouvoir écrire un client/serveur, néamoins certaines choses ne sont pas tout à fait clair, si vous pouvez me corriger sur certains passages, n’hésitez pas à me le faire savoir.
Je suis joignable par mail à knarf2_AT_laposte_DOT_net
et sur IRC à #diobla@Quakenet.org.
spéciauxpermettant de faire des attaques, ou de se défendre.
La dernière version officielle du client (et du protocole) est
la 1.13 . Le port standart du serveur TetriNET est le port 31457.
Le protocole consiste en de simple commandes ASCII (ie. fait de
caractère) d’une ligne dont le caractère final (le séparateur de
ligne) a pour valeur 0xFF.
Le client renvoie ensuite son équipe.
Les joueurs peuvent discuter entre eux, avant qu’un joueur ayant le droit de lancer une partie (généralement celui à l’id-joueur 1 le fasse. Le serveur initialise la partie, en définissant certaines caractéristiques.
Durant la partie, les clients envoie l’état de leur jeu, reçoivent du serveur celui des autres, des spéciaux, des messages, etc.
Petit à petit les joueurs perdent, et le signale au serveur. Lorsqu’un gagnant est déclaré, le serveur le signale à tout le monde.
Le système de channel est géré par le serveur : /join #chan est envoyé tel quel au serveur. (Voir Commandes spécifiques au serveur) L’id-joueur change à chaque changement de channel et un joueur ne peut être que sur un seul channel à la fois. Il ne peut y avoir plus de 6 joueurs dans un channel et donc dans une partie.
Les commandes client, c’est-à-dire tout ce que le client envoie au serveur, sont listées ici.
Le hello message
est la première information envoyé au serveur lors
de la connection. C’est une simple chaine de caractère encodé
contenant l’ip du serveur, le nick du client et la version du
protocole qu’il utilise. Voici le format de la chaine non-encodé :
tetrisstart <nick> 1.13
On peut rapidement trouver sur internet une implémentation de la fonction d’encodage.
Permet au client de lancer/arreter une partie.
Necessite un id 1 ou 2. (dépend manifestement de l’implémentation)
startgame <etat> <id>
Permet au client de mettre/enlever la pause lors d’une partie.
Necessite un id 1 ou 2.
pause <etat> <id>
Permet de définir l’équipe du client. Généralement envoyé lorsque l’équipe change, ou lorsque que l’on rejoint un channel.
team <id>
team <id> <team>
Lorsque team n’est pas fourni, le joueur n’a pas d’équipe. (Il est seul)
Les différentes façons de recevoir des messages et action (à la IRC).
Message hors-partie.
pline <id> <msg>
plineact <id> <msg>
Message de jeu.
gmsg <nick> <msg>
Voici un tableau de correspondance :
| Type | Effet |
| cs1 | 1 Line Added |
| cs2 | 2 Lines Added |
| cs4 | 4 Lines Added |
| a | Add Line |
| c | Clear Line |
| n | Nuke Field |
| r | Clear Random |
| s | Switch Field |
| b | Clear Specials |
| g | Block Gravity |
| q | Blockquake |
| o | Block Bomb |
Voir les règles de TetriNET pour une description plus précise.
Reçut et envoyé au cours d’une partie, représente la totalité ou une partie du jeu d’un joueur.
f <id> <field>
'0' (48)
représentant l’état du bloc suivit de N paires de caractère B
au code ASCII supérieur ou égale à '0' correspondant
respectivement au coordonnées x et y du bloc.
Le tout premier caractère de la description du bloc est donc de type A, c’est ainsi que l’on reconnait la méthode d’envoie de field.
a, b, c, g, n, o, q, r, s.
Un exemple vaut mieux qu’un long discours, voici une
implémentation en C où s correspond un pointeur de caractère
sur la chaîne à décoder, bloc un entier représentant l’état
d’un bloc et field un tableau de caractère représentant le
field.
while (*s) {
if (*s < '0') {
bloc = *s - '!';
else {
x = *s - '3';
y = (*++s) - '3';
field[y][x] = bloc;
}
s++;
}
}
On preferera envoyer le field avec la deuxième méthode lorsque les changements sont minimes (ajout d’une pièce, etc) et avec la première pour l’envoi du tout premier field ou pour le remplissage du field lorsque que le joueur perd.
Envoyé lorsque que le joueur change de niveau.
lvl <id> <lvl>
Envoyé lorsque le client perd.
playerlost <id>
id-joueur du client.
Toute les commandes supplémentaire sont gérées de cette manière.
pline <id> /<cmd>
Commande
Cela va du /join #chan à /help, etc. Les commandes sont propres au serveur.
Les commandes serveurs, c’est-à-dire tout ce que le serveur envoie aux clients, sont listées ici.
Erreur envoyé par le serveur lors de la connection
noconnecting <err>
Raison de la déconnection.
Liste des meilleurs joueurs/équipe du serveur.
winlist <entry1> <entry2> <...>
playerou
team, indique si l’entrée correspond au nick d’un joueur ou au nom d’une équipe.
Le nombre d’entrée peut varier de aucune à beaucoup.
Donne l’id-joueur du client. Est envoyé à chaque chagement de channel (et à la connection).
playernum <id>
Nouvel id-joueur du client.
Envoyé lorsqu’un joueur rejoin la partie.
playerjoin <id> <nick>
Envoyé lorsqu’un joueur quitte le chan.
playerleave <id>
Voir playerjoin.
Lorsqu’un client change d’équipe, il envoit un (team). Le serveur envoie par la suite l’information à tous les joueurs du channel.
team <id>
team <id> <team>
Voir team (client).
Lorsque qu’il ne reste plus que des joueurs de la même équipe en jeu, (ou qu’il ne reste plus qu’un joueur, dans le cas de joueurs sans équipe) ces derniers sont déclarés vainqueur. La commande suivante est envoyée à chacun des joueurs du channel.
playerwon <id>
L’équipe du joueur est considérée gagnante (si le joueur en à une).
Lorsqu’un joueur émet un message/action, le serveur fait passer le message à tous les autre joueurs du channel.
Note: L’id-joueur du serveur est 0.
Voir Messages et actions (client).
Après avoir reçut un startgame d’un joueur authorisé, le serveur envoie une commande spécifiant les caractéristique de la partie :
newgame <s> <inlvl> <lpl> <iclvl> <sl> <sco> <sca> <bf> <sf> <alvl> <old>
Nombre maximum de spéciaux dans l’inventaire.
14% de bloc 3, 14% de bloc 5, 15% de bloc 2, 14% de
bloc 4, 14% de bloc 6, 14% de bloc 7, 15% de bloc
1. [1-9] respectivement [abcgnoqrs]), permettant de
constituder un pourcentage de spécial.
Lorsque il est à 1, le gain de niveau d’un joueur est valable pour tous les joueurs. (ie. les joueurs ont tous le même niveau au tout au long de la partie.)
Lorsqu’il est à 1, un joueur faisant N lignes avec N > 1,
ajoutera N lignes (ou N-1 lignes si N < 4) du serveur
(id-joueur 0) à lui même.
Cette commande est envoyé au joueur qui rejoint un channel dans lequel une partie est déjà en cours.
ingame
pause <etat>
Vaut 1 ou 0, correspond respectivement à mettre en pause,
et l’enlever.
Indique la fin de la partie en cours. Cette commande est envoyé lorsqu’un joueur remporte la partie ou quand il ne reste plus d’adversaires (s’il se sont déconnecté par exemple), etc.
endgame
Après avoir reçut un field d’un joueur, le serveur fait passer le message aux autre joueurs.
Voir Field du joueur (client).
Après avoir reçut un changment de niveau d’un joueur, le serveur fait passer le message aux autre joueurs.
Voir Level du joueur (client).
Le terrain de jeu (ou field) de chaque joueurs fait 12 blocs de
larges pour 22 blocs de hauteur. Un joueur a perdu lorsque l’une de
ses pièces dépasse la 22eme ligne de son jeu.
Les pièces sont les groupements de blocs qui tombent
lors d’une
partie de TetriNET. Chaque pièce possède un numéro [1-7]), et chaque
bloc qui la composent porte tous un même numéro, ([1-5])
correspondant à la couleur.
La pièce 1 : la barre
####
La pièce 2 : le carré
##
##
La pièce 3 : le J
#
#
##
La pièce 4 : le L
#
#
##
La pièce 5 : le Z
##
##
La pièce 6 : le S
##
##
La pièce 7 : le T
#
###
La sélection des pièces est aléotoire, mais essaye de respecter la fréquence imposé par le serveur.