R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
Lobby.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** rtype
4** File description:
5** Lobby.cpp - Main lobby implementation
6*/
7
11
12namespace server {
13
14 // Initialize static member
15 std::atomic<uint64_t> Lobby::_nextRoomId{1};
16
17 Lobby::Lobby(std::shared_ptr<RoomManager> roomManager) : _roomManager(roomManager) {
18 LOG_INFO("Lobby created");
19 }
20
21 bool Lobby::addPlayer(uint32_t playerId, const std::string &playerName) {
22 std::lock_guard<std::mutex> lock(_mutex);
23
24 if (_players.find(playerId) != _players.end()) {
25 LOG_WARNING("Player ", playerId, " already in lobby");
26 return false;
27 }
28
29 LobbyPlayer player;
30 player.playerId = playerId;
31 player.playerName = playerName;
32 player.isReady = false;
33 player.inMatchmaking = false;
34
35 _players[playerId] = player;
36 LOG_INFO("✓ Player '", playerName, "' (", playerId, ") joined lobby (", _players.size(), " players)");
37 return true;
38 }
39
40 bool Lobby::removePlayer(uint32_t playerId) {
41 std::lock_guard<std::mutex> lock(_mutex);
42
43 auto it = _players.find(playerId);
44 if (it == _players.end()) {
45 return false;
46 }
47
48 if (it->second.inMatchmaking && _roomManager) {
49 _roomManager->removePlayerFromMatchmaking(playerId);
50 }
51
52 _players.erase(it);
53 LOG_INFO("✓ Player ", playerId, " left lobby (", _players.size(), " players remaining)");
54 return true;
55 }
56
57 bool Lobby::updatePlayerName(uint32_t playerId, const std::string &newName) {
58 std::lock_guard<std::mutex> lock(_mutex);
59
60 auto it = _players.find(playerId);
61 if (it == _players.end()) {
62 LOG_WARNING("Cannot update name - player ", playerId, " not in lobby");
63 return false;
64 }
65
66 std::string oldName = it->second.playerName;
67 it->second.playerName = newName;
68 LOG_INFO("✓ Player ", playerId, " name updated: '", oldName, "' → '", newName, "'");
69 return true;
70 }
71
72 const LobbyPlayer *Lobby::getPlayer(uint32_t playerId) const {
73 std::lock_guard<std::mutex> lock(_mutex);
74
75 auto it = _players.find(playerId);
76 if (it != _players.end()) {
77 return &it->second;
78 }
79
80 return nullptr;
81 }
82
83 std::vector<LobbyPlayer> Lobby::getAllPlayers() const {
84 std::lock_guard<std::mutex> lock(_mutex);
85
86 std::vector<LobbyPlayer> players;
87 players.reserve(_players.size());
88
89 for (const auto &[id, player] : _players) {
90 players.push_back(player);
91 }
92
93 return players;
94 }
95
96 size_t Lobby::getPlayerCount() const {
97 std::lock_guard<std::mutex> lock(_mutex);
98 return _players.size();
99 }
100
101 bool Lobby::startMatchmaking(uint32_t playerId) {
102 std::lock_guard<std::mutex> lock(_mutex);
103
104 auto it = _players.find(playerId);
105 if (it == _players.end()) {
106 LOG_WARNING("Cannot start matchmaking - player ", playerId, " not in lobby");
107 return false;
108 }
109
110 if (it->second.inMatchmaking) {
111 LOG_WARNING("Player ", playerId, " already in matchmaking");
112 return false;
113 }
114
115 if (!_roomManager) {
116 LOG_ERROR("Cannot start matchmaking - room manager not initialized");
117 return false;
118 }
119
120 it->second.inMatchmaking = true;
121 _roomManager->addPlayerToMatchmaking(playerId);
122
123 LOG_INFO("✓ Player ", playerId, " started matchmaking");
124 return true;
125 }
126
127 bool Lobby::cancelMatchmaking(uint32_t playerId) {
128 std::lock_guard<std::mutex> lock(_mutex);
129
130 auto it = _players.find(playerId);
131 if (it == _players.end()) {
132 return false;
133 }
134
135 if (!it->second.inMatchmaking) {
136 return false;
137 }
138
139 if (_roomManager) {
140 _roomManager->removePlayerFromMatchmaking(playerId);
141 }
142
143 it->second.inMatchmaking = false;
144 LOG_INFO("✓ Player ", playerId, " cancelled matchmaking");
145 return true;
146 }
147
148 bool Lobby::joinRoom(uint32_t playerId, const std::string &roomId) {
149 std::lock_guard<std::mutex> lock(_mutex);
150
151 auto playerIt = _players.find(playerId);
152 if (playerIt == _players.end()) {
153 LOG_WARNING("Cannot join room - player ", playerId, " not in lobby");
154 return false;
155 }
156
157 if (!_roomManager) {
158 LOG_ERROR("Cannot join room - room manager not initialized");
159 return false;
160 }
161
162 auto room = _roomManager->getRoom(roomId);
163 if (!room) {
164 LOG_WARNING("Cannot join room - room '", roomId, "' not found");
165 return false;
166 }
167
168 if (room->join(playerId)) {
169 LOG_INFO("✓ Player ", playerId, " joined room '", roomId, "'");
170 return true;
171 }
172
173 return false;
174 }
175
176 std::string Lobby::createCustomRoom(uint32_t hostPlayerId, const std::string &roomName, size_t maxPlayers,
177 bool isPrivate) {
178 std::lock_guard<std::mutex> lock(_mutex);
179
180 auto playerIt = _players.find(hostPlayerId);
181 if (playerIt == _players.end()) {
182 LOG_WARNING("Cannot create room - player ", hostPlayerId, " not in lobby");
183 return "";
184 }
185
186 if (!_roomManager) {
187 LOG_ERROR("Cannot create room - room manager not initialized");
188 return "";
189 }
190
191 // Generate unique room ID using atomic counter to prevent collisions
192 uint64_t roomNumber = _nextRoomId.fetch_add(1, std::memory_order_relaxed);
193 std::string roomId = "custom_" + std::to_string(hostPlayerId) + "_" + std::to_string(roomNumber);
194
195 auto room = _roomManager->createRoom(roomId, roomName, maxPlayers, isPrivate);
196 if (!room) {
197 LOG_ERROR("Failed to create custom room");
198 return "";
199 }
200
201 if (room->join(hostPlayerId)) {
202 room->setHost(hostPlayerId);
203 LOG_INFO("✓ Player ", hostPlayerId, " created custom room '", roomName, "' (", roomId, ")");
204 return roomId;
205 }
206
207 _roomManager->removeRoom(roomId);
208 return "";
209 }
210
211 void Lobby::setPlayerReady(uint32_t playerId, bool ready) {
212 std::lock_guard<std::mutex> lock(_mutex);
213
214 auto it = _players.find(playerId);
215 if (it != _players.end()) {
216 it->second.isReady = ready;
217 LOG_INFO("Player ", playerId, " ready status: ", (ready ? "ready" : "not ready"));
218 }
219 }
220
221} // namespace server
#define LOG_INFO(...)
Definition Logger.hpp:181
#define LOG_ERROR(...)
Definition Logger.hpp:183
#define LOG_WARNING(...)
Definition Logger.hpp:182
bool updatePlayerName(uint32_t playerId, const std::string &newName)
Update a player's display name.
Definition Lobby.cpp:57
bool startMatchmaking(uint32_t playerId)
Start matchmaking for a player.
Definition Lobby.cpp:101
std::mutex _mutex
Definition Lobby.hpp:143
bool joinRoom(uint32_t playerId, const std::string &roomId)
Join a specific room by ID.
Definition Lobby.cpp:148
std::shared_ptr< RoomManager > _roomManager
Definition Lobby.hpp:142
std::vector< LobbyPlayer > getAllPlayers() const
Get all players in lobby.
Definition Lobby.cpp:83
bool addPlayer(uint32_t playerId, const std::string &playerName)
Add a player to the lobby.
Definition Lobby.cpp:21
std::string createCustomRoom(uint32_t hostPlayerId, const std::string &roomName, size_t maxPlayers, bool isPrivate)
Create a custom room.
Definition Lobby.cpp:176
void setPlayerReady(uint32_t playerId, bool ready)
Set player ready status (for custom rooms)
Definition Lobby.cpp:211
size_t getPlayerCount() const
Get number of players in lobby.
Definition Lobby.cpp:96
std::unordered_map< uint32_t, LobbyPlayer > _players
Definition Lobby.hpp:141
bool cancelMatchmaking(uint32_t playerId)
Cancel matchmaking for a player.
Definition Lobby.cpp:127
static std::atomic< uint64_t > _nextRoomId
Definition Lobby.hpp:146
const LobbyPlayer * getPlayer(uint32_t playerId) const
Get player info.
Definition Lobby.cpp:72
Lobby(std::shared_ptr< RoomManager > roomManager)
Construct a lobby.
Definition Lobby.cpp:17
bool removePlayer(uint32_t playerId)
Remove a player from the lobby.
Definition Lobby.cpp:40
Information about a player in the lobby.
Definition Lobby.hpp:26
uint32_t playerId
Definition Lobby.hpp:27
std::string playerName
Definition Lobby.hpp:28