15 _scheduler(scheduler),
19 clients, world, notifier, config, _clock,
20 [this](int connectionId, int playerId) { this->
_onAiJoined(connectionId, playerId); })
61 int playerId = conn.playerId();
106 if (
_queues[connectionId].size() >= 10)
return;
107 _queues[connectionId].push_back(*cmd);
113 auto& queue =
_queues[connectionId];
146 _clients.
send(connectionId, std::to_string(slots) +
"\n");
154 [
this, connectionId, playerId] {
155 if (!_world.getPlayers().count(playerId)) return;
156 if (!_world.consumeFood(playerId)) {
157 _world.removePlayer(playerId);
158 _clients.send(connectionId,
"dead\n");
159 _pendingDisconnects.push_back(connectionId);
161 _startStarvationTimer(connectionId, playerId);
168 std::vector<int> result;
static std::optional< Ai::Command > parse(std::string_view line)
Parse one line from an AI client (no trailing newline).
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 _handleMct(int connectionId)
void _handleFork(int connectionId)
std::chrono::microseconds gameElapsed() const
Wall-clock time since server start (single source for stu and the win banner).
void _handleSst(int freq)
void _handlePlv(int connectionId, int playerId)
void _dispatchGui(int connectionId, const std::string &line)
void _startStarvationTimer(int connectionId, int playerId)
HandshakeHandler _handshakeHandler
static constexpr int STARVATION_INTERVAL_MS
one food is consumed every 126 time units (1 unit = 1/freq seconds)
double gameTicks() const
Total game ticks elapsed (freq integrated over time). For the win banner.
void onNewConnection(int connectionId)
New socket connected: start its handshake.
void _onAiJoined(int connectionId, int playerId)
Fired on AI promotion: stamp team join, then start its food timer.
void _handleIncantation(int connectionId)
void _handleTake(int connectionId, ResourceType resource)
void _handlePin(int connectionId, int playerId)
void _handleLeft(int connectionId)
void _handleLook(int connectionId)
CommandDispatcher(ClientManager &clients, World &world, GuiNotifier ¬ifier, const ServerConfig &config, Scheduler &scheduler)
void _handleStu(int connectionId)
void _handleSgt(int connectionId)
void _handleMsz(int connectionId)
void onDisconnect(int connectionId)
Socket dropped: clean up its queue and player.
void _executeNext(int connectionId)
Run the next queued AI command (or go idle if none left).
void dispatch(int connectionId, const std::string &line)
Route one line from a client.
void _handleBct(int connectionId, int x, int y)
std::unordered_map< int, bool > _hasActive
std::optional< GameClock::Stamp > teamJoin(const std::string &team) const
When team's first player joined, or nullopt if it never did.
void _handleForward(int connectionId)
void _dispatchAi(int connectionId, const std::string &line)
void _handleConnectNbr(int connectionId)
void _handleInventory(int connectionId)
std::vector< int > _pendingDisconnects
std::vector< int > drainPendingDisconnects()
Take the list of ids the server should disconnect this cycle.
std::unordered_map< int, std::deque< Ai::Command > > _queues
void _handleTna(int connectionId)
void _handleBroadcast(int connectionId, const std::string &msg)
void _handleRight(int connectionId)
void _handlePpo(int connectionId, int playerId)
void _handleSet(int connectionId, ResourceType resource)
void _handleEject(int connectionId)
int playerId() const
Player this connection drives (-1 for GUI / not yet assigned).
std::optional< Stamp > joinOf(const std::string &team) const
The join stamp for team, or nullopt if the team never joined.
void recordJoin(const std::string &team)
double ticks() const
Total ticks elapsed: integral of freq over time. Fractional by nature.
std::chrono::microseconds elapsed() const
Wall-clock time since construction.
void removeGui(int connectionId)
static std::optional< Gui::Request > parse(std::string_view line)
Parse one line from a GUI client (no trailing newline).
void onNewConnection(int connectionId)
New socket: send the "WELCOME" greeting.
void onLine(int connectionId, const std::string &line)
The client's reply (its team name).
Priority queue of timed callbacks. Drives all game timing.
void schedule(std::chrono::milliseconds delay, std::function< void()> cb)
Pure game state - no networking, no scheduling.
const std::unordered_map< int, Player > & getPlayers() const
bool isGameEnded() const
True once a team has won. Game logic stops reacting to AI commands.
void removePlayer(int id)
Player & getPlayer(int id)
int teamEggCount(const std::string &team) const
std::variant< Forward, Right, Left, Look, Inventory, Broadcast, ConnectNbr, Fork, Eject, Take, Set, Incantation > Command
Represents the configuration for the server application, described by: