Handshake¶
À la connexion, le serveur envoie immédiatement WELCOME\n à tout nouveau
client (PendingClient, server/srcs/network/PendingClient.cpp). La première
ligne renvoyée par le client détermine ensuite son type :
- si c'est le mot-clé réservé
GRAPHIC, le client devient un GUI ; - sinon, la ligne est interprétée comme un nom d'équipe : le client devient une IA s'il reste un œuf disponible dans cette équipe.
Tout l'aiguillage est réalisé par ClientSessionManager
(server/srcs/core/ClientSessionManager.cpp).
Handshake IA¶
sequenceDiagram
participant IA as zappy_ai
participant S as Serveur
S->>IA: WELCOME
IA->>S: <nom-équipe>
Note over S: éclosion d'un œuf de l'équipe
S->>IA: <CLIENT-NUM> (slots restants)
S->>IA: <X> <Y> (taille du monde)
Le client envoie son nom d'équipe. Si l'équipe existe et qu'il reste au moins un œuf libre, le serveur :
- fait éclore un œuf en un nouveau joueur (
Player) ; - renvoie
<CLIENT-NUM>\n: le nombre de slots restants dans l'équipe, c'est-à-dire le nombre d'œufs encore disponibles après éclosion ; - renvoie
<X> <Y>\n: la largeur et la hauteur du monde.
(ClientSessionManager.cpp:123-127.)
Échec¶
Équipe inconnue ou aucun œuf disponible
Si le nom d'équipe est inconnu ou que l'équipe n'a plus d'œuf, le serveur
répond ko\n puis ferme la connexion (ClientSessionManager.cpp).
Exemple (succès)¶
Ici l'équipe team1 avait 6 œufs : après éclosion il en reste 5, et le monde
mesure 10 × 10.
Côté IA
Le client IA attend la chaîne exacte WELCOME, envoie le nom d'équipe puis
lit CLIENT-NUM et X Y. L'implémentation suppose que ces deux dernières
lignes arrivent dans le même paquet (splitlines()), ce qui est fragile en
cas de fragmentation TCP — voir
Connexion IA et Limitations connues.
Référence : ai/src/network/connection.py (do_handshake).
Handshake GUI¶
sequenceDiagram
participant GUI as zappy_gui
participant S as Serveur
S->>GUI: WELCOME
GUI->>S: GRAPHIC
S->>GUI: msz X Y
S->>GUI: sgt T
loop pour chaque équipe
S->>GUI: tna <nom-équipe>
end
loop pour chaque tuile (mct → bct)
S->>GUI: bct X Y q0 q1 q2 q3 q4 q5 q6
end
loop pour chaque joueur
S->>GUI: pnw #id X Y O L N
S->>GUI: plv #id L
S->>GUI: pin #id X Y q0..q6
end
loop pour chaque œuf
S->>GUI: enw #œuf #joueur X Y
end
Dès réception de GRAPHIC, le serveur réalise un dump initial complet de
l'état du monde, dans cet ordre (ClientSessionManager.cpp:31-66) :
msz X Y— taille de la carte ;sgt T— fréquence/unité de temps courante ;tna <nom>— un message par équipe ;- la carte entière :
sendMctparcourt toutes les tuiles et émet unbctpar tuile (le GUI ne reçoit donc jamais demctagrégé, voir l'avertissement plus bas) ; - pour chaque joueur déjà présent :
pnw, puisplv, puispin; - pour chaque œuf existant :
enw.
Exemple (extrait)¶
C -> S : GRAPHIC
S -> C : msz 10 10
S -> C : sgt 100
S -> C : tna team1
S -> C : tna team2
S -> C : bct 0 0 1 0 0 0 0 0 0
S -> C : bct 1 0 0 1 0 0 0 0 0
...
S -> C : bct 9 9 0 0 0 0 0 0 0
S -> C : pnw #1 4 5 2 1 team1
S -> C : plv #1 1
S -> C : pin #1 4 5 10 0 0 0 0 0 0
S -> C : enw #3 #-1 7 2
Dans pnw #1 4 5 2 1 team1, le joueur #1 est en (4,5), orienté 2 (Est),
de niveau 1, équipe team1. Le format détaillé de chaque événement est donné
dans GUI ↔ Serveur.
mct toujours détaillé en bct
Le serveur n'émet jamais d'événement mct consolidé : il l'« explose » en
une série de bct (un par tuile). Côté GUI, le handler onMct existe mais
est volontairement un no-op. Voir Limitations connues.