Zappy Server
C++ game server: world, rules, scheduler, network
Loading...
Searching...
No Matches
HandshakeHandler.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <random>
5
8
10 const ServerConfig& config, const GameClock& clock,
11 PromotedCallback onPromoted)
12 : _clients(clients),
13 _world(world),
14 _notifier(notifier),
15 _config(config),
16 _clock(clock),
17 _onPromoted(onPromoted)
18{
19}
20
22{
23 _clients.send(connectionId, "WELCOME\n");
24}
25
26void HandshakeHandler::onLine(int connectionId, const std::string& line)
27{
28 if (line == "GRAPHIC") {
29 _promoteToGui(connectionId);
30 return;
31 }
32 // Game over: no new players may join, but GUI viewers still may (above).
33 if (_world.isGameEnded()) {
34 _reject(connectionId);
35 return;
36 }
37 auto it = std::find(_config.teamNames.begin(), _config.teamNames.end(), line);
38 if (it == _config.teamNames.end()) {
39 _reject(connectionId);
40 return;
41 }
42 if (_world.teamEggCount(line) == 0) {
43 _reject(connectionId);
44 return;
45 }
46 _promoteToAi(connectionId, line);
47}
48
49void HandshakeHandler::_promoteToGui(int connectionId)
50{
51 auto& conn = _clients.getConnection(connectionId);
53 _notifier.addGui(connectionId);
54
56 for (int y = 0; y < _config.height; y++)
57 for (int x = 0; x < _config.width; x++)
58 _notifier.send(connectionId, Serializer::bct(x, y, _world.at(x, y).resources));
59 for (auto& name : _config.teamNames) _notifier.send(connectionId, Serializer::tna(name));
60 _notifier.send(connectionId, Serializer::sgt(_clock.freq()));
61 for (auto& [id, p] : _world.getPlayers())
62 _notifier.send(connectionId,
63 Serializer::pnw(p.id, p.x, p.y, p.orientation, p.level, p.teamName));
64 // Initial eggs (parentPlayerId < 0) replay as sse; player-laid eggs as enw,
65 // matching how World::_spawnEgg first announced them.
66 for (auto& [id, egg] : _world.getEggs()) {
67 if (egg.parentPlayerId < 0)
68 _notifier.send(connectionId, Serializer::sse(egg.id, egg.teamName, egg.x, egg.y));
69 else
70 _notifier.send(connectionId, Serializer::enw(egg.id, egg.parentPlayerId, egg.x, egg.y));
71 }
72}
73
74void HandshakeHandler::_promoteToAi(int connectionId, const std::string& teamName)
75{
76 std::uniform_int_distribution<int> dori(1, 4);
77 static std::mt19937 rng{std::random_device{}()};
78 auto orientation = static_cast<Orientation>(dori(rng));
79
80 // A player only spawns by hatching one of the team's eggs. popEggForTeam
81 // fires onEggHatched through the observers (GUI ebo, logging).
82 auto egg = _world.popEggForTeam(teamName);
83 if (!egg) {
84 _reject(connectionId);
85 return;
86 }
87
88 int playerId = _world.addPlayer(connectionId, teamName, egg->x, egg->y, orientation);
90 _clients.getConnection(connectionId).setPlayerId(playerId);
91
92 int slotsLeft = _world.teamEggCount(teamName);
93 _clients.send(connectionId, std::to_string(slotsLeft) + "\n");
94 _clients.send(connectionId,
95 std::to_string(_config.width) + " " + std::to_string(_config.height) + "\n");
96
97 _onPromoted(connectionId, playerId);
98}
99
100void HandshakeHandler::_reject(int connectionId)
101{
102 _clients.send(connectionId, "ko\n");
103 _clients.disconnect(connectionId);
104}
std::function< void(int connectionId, int playerId)> PromotedCallback
Orientation
Owns every client socket and runs the poll() loop.
void send(int connectionId, const std::string &msg)
Queue msg to be sent to a client (flushed during poll()).
Connection & getConnection(int connectionId)
Access the underlying Connection (e.g. to set its type/playerId).
void disconnect(int connectionId)
Close a client and drop its connection.
void setType(ClientType type)
void setPlayerId(int id)
Single owner of game frequency and elapsed game time.
Definition GameClock.hpp:22
int freq() const
Definition GameClock.hpp:32
void addGui(int connectionId)
void send(int connectionId, const std::string &msg)
void onNewConnection(int connectionId)
New socket: send the "WELCOME" greeting.
const ServerConfig & _config
const GameClock & _clock
void onLine(int connectionId, const std::string &line)
The client's reply (its team name).
void _promoteToGui(int connectionId)
GuiNotifier & _notifier
void _reject(int connectionId)
PromotedCallback _onPromoted
ClientManager & _clients
void _promoteToAi(int connectionId, const std::string &teamName)
HandshakeHandler(ClientManager &clients, World &world, GuiNotifier &notifier, const ServerConfig &config, const GameClock &clock, PromotedCallback onPromoted)
Pure game state - no networking, no scheduling.
Definition World.hpp:47
const std::unordered_map< int, Player > & getPlayers() const
Definition World.cpp:402
std::optional< Egg > popEggForTeam(const std::string &teamName)
Definition World.cpp:244
Tile & at(int x, int y)
Access a tile by position. Map is toroidal, coordinates wrap.
Definition World.cpp:12
int addPlayer(int connectionId, const std::string &teamName, int x, int y, Orientation orientation)
Definition World.cpp:58
bool isGameEnded() const
True once a team has won. Game logic stops reacting to AI commands.
Definition World.cpp:417
const std::unordered_map< int, Egg > & getEggs() const
Definition World.cpp:403
int teamEggCount(const std::string &team) const
Definition World.cpp:222
std::string msz(int x, int y)
Map size. Wire: msz X Y\n
std::string tna(const std::string &teamName)
Team name (one per team). Wire: tna NAME\n
std::string sgt(int freq)
Reply to "sgt": current time unit frequency. Wire: sgt F\n
std::string bct(int x, int y, const Resources &r)
Tile content (resources on it). Wire: bct X Y q q q q q q q\n
std::string sse(int eggId, const std::string &teamName, int x, int y)
std::string pnw(int id, int x, int y, Orientation o, int level, const std::string &team)
New player connected. Wire: pnw #N X Y O L NAME\n (L = level)
std::string enw(int eggId, int playerId, int x, int y)
Egg laid by a player. Wire: enw #E #N X Y\n (E = egg, N = parent)
Represents the configuration for the server application, described by:
Definition Args.hpp:17
int height
Definition Args.hpp:20
std::vector< std::string > teamNames
Definition Args.hpp:21
int width
Definition Args.hpp:19
Resources resources
Definition Tile.hpp:11