R-Type  2
Doom but in better
Loading...
Searching...
No Matches
server.cpp
Go to the documentation of this file.
1#include "server.hpp"
2#include <iostream>
3
4Server::Server(asio::io_context &io, unsigned short port)
5 : socket_(io, asio::ip::udp::endpoint(asio::ip::udp::v4(), port)),
6 gameManager_([this](uint32_t cid, const Message &msg) {
7 // A lambda so gameManager can call back to sendToClient
8 this->sendToClient(cid, msg);
9 })
10{
11 doReceive();
12}
13
14void Server::doReceive()
15{
16 socket_.async_receive_from(
17 asio::buffer(recvBuffer_), remoteEndpoint_,
18 [this](std::error_code ec, std::size_t bytesRecv) {
19 if (!ec && bytesRecv > 0) {
20 handleMessage(bytesRecv);
21 }
22 doReceive();
23 }
24 );
25}
26
27void Server::handleMessage(std::size_t bytesReceived)
28{
29 Message msg;
30 if (!decodeMessage(recvBuffer_.data(), bytesReceived, msg)) {
31 std::cout << "[Server] Invalid message from " << remoteEndpoint_ << "\n";
32 return;
33 }
34
35 // Identify or create client ID
36 uint32_t clientId = clientManager_.resolveClientID(remoteEndpoint_);
37 // For debugging
38 // std::cout << "[Server] Received type=" << msg.type
39 // << " from clientId=" << clientId << "\n";
40
41 // Example simple switch:
42 switch (msg.type) {
43 case 1: { // CONNECT
44 std::cout << "[Server] Client " << clientId
45 << " connected from " << remoteEndpoint_ << "\n";
46
47 auto sync = gameManager_.syncClientToGame(clientId);
48 std::cout << "[Server] Syncing " << clientId << " to game...\n";
49 for (auto &packet : sync) {
50 Message msg;
51 decodeMessage(packet.c_str(), packet.size(), msg);
52 sendToClient(clientId, msg);
53 }
54 std::cout << "[Server] Synced " << clientId << " to game.\n";
55 //gameManager_.assignClientToGame(clientId); << deprecated
56 break;
57 }
58 case 2: { // DISCONNECT
59 std::cout << "[Server] Client " << clientId << " disconnected.\n";
60 gameManager_.removeClientFromGame(clientId);
61 clientManager_.removeClient(remoteEndpoint_);
62 break;
63 }
64 case 0xFE: { // HANDSHAKE
65 sendToClient(clientId, { 0xFE, {} });
66 std::cout << "[Server] Handshaked client " << clientId << ".\n";
67 break;
68 }
69 default: {
70 // Forward to game manager to interpret
71 uint32_t gID = gameManager_.getGameIdForClient(clientId);
72 if (gID != 0) {
73 gameManager_.handleGameMessage(gID, clientId, msg);
74 }
75 break;
76 }
77 }
78}
79
80void Server::sendToClient(uint32_t clientId, const Message &msg)
81{
82 // 1) Get endpoint from clientManager
83 auto ep = clientManager_.getEndpointForId(clientId);
84 if (ep == asio::ip::udp::endpoint()) {
85 std::cout << "[Server] No endpoint known for client " << clientId << "\n";
86 return;
87 }
88
89 // 2) Encode
90 auto buffer = encodeMessage(msg);
91
92 // 3) Capping the send to avoid ddossing the clients
93 std::this_thread::sleep_for(std::chrono::milliseconds(20));
94
95
96 // 4) async_send
97 // std::cout << "Sending message" << std::endl;
98 socket_.async_send_to(
99 asio::buffer(buffer),
100 ep,
101 [this](std::error_code ec, std::size_t bytesSent) {
102 if (ec) {
103 std::cout << "[Server] sendToClient error: " << ec.message() << "\n";
104 }
105 }
106 );
107}
asio::ip::udp::endpoint getEndpointForId(uint32_t clientId)
Returns the endpoint for a given clientId if known, else a default-constructed endpoint.
uint32_t resolveClientID(const asio::ip::udp::endpoint &ep)
void removeClient(const asio::ip::udp::endpoint &ep)
uint32_t getGameIdForClient(uint32_t clientId) const
Get the game ID for a client, or 0 if none.
std::forward_list< std::string > syncClientToGame(uint32_t clientId)
Gets the current game state for syncing.
void removeClientFromGame(uint32_t clientId)
Remove a client from whichever game they are in.
void handleGameMessage(uint32_t gameId, uint32_t clientId, const Message &msg)
Handle a message from a client in a specific game.
Server(asio::io_context &io, unsigned short port)
Constructs the Server, binding a UDP socket to the specified port.
Definition server.cpp:4
void sendToClient(uint32_t clientId, const Message &msg)
Sends a Message to a specific client by ID (uses clientManager to find endpoint).
Definition server.cpp:80
std::vector< uint8_t > encodeMessage(const Message &msg)
Encodes a Message into a raw buffer (2-byte type, 2-byte length, then payload).
bool decodeMessage(const char *data, size_t length, Message &out)
Decodes a raw buffer into a Message (2-byte type, 2-byte length, then payload).
Minimal network message with a 4-byte header (type + length) and a payload.
Definition message.hpp:9
uint8_t type
Could map to messageType in GameMessage.hpp (CONNECT, DISCONNECT, etc.)
Definition message.hpp:10