25 , _networkSync(networkSync)
29 _rooms[lobby->getId()] = lobby;
31 log::info(
"Default Lobby created with ID {}", lobby->getId());
37 for (
auto &[roomId, roomPtr] :
_rooms) {
39 roomPtr->update(0, dt);
44 const std::string &roomName,
45 uint8_t maxPlayers,
float difficulty,
47 uint32_t levelId, uint32_t seed,
48 uint32_t durationMinutes)
55 difficulty, speed, type, sessionId,
56 levelId, seed, durationMinutes);
57 _rooms.emplace(newId, room);
59 log::info(
"Room '{}' created with ID {} by session {}", roomName, newId,
66 std::shared_ptr<Room> room;
68 "Player {} (Session ID {}) attempting to join Room ID {}{}",
69 player->getUsername(), player->getId(), roomId,
70 asSpectator ?
" as spectator" :
"");
73 " Could not leave previous room, maybe first connection ?. Player {} (Session ID {})",
74 player->getId(), roomId);
77 std::lock_guard lock(
_mutex);
79 auto it =
_rooms.find(roomId);
82 "Failed to join Player {} to Room ID {}. Room does " "not "
85 player->getId(), roomId);
87 response << static_cast<uint8_t>(0);
94 if (room->isBanned(player->getUsername())) {
96 "Failed to join Player {} to Room ID {}. Player is banned.",
97 player->getId(), roomId);
100 response << static_cast<uint8_t>(0);
108 "Failed to join Player {} to Room ID {}. Game already started.",
109 player->getId(), roomId);
112 response << static_cast<uint8_t>(0);
118 if (!asSpectator && !room->canJoin()) {
120 "Failed to join Player {} to Room ID {}. Room is full.",
121 player->getId(), roomId);
124 response << static_cast<uint8_t>(0);
133 if (!room->addPlayer(player, joinType)) {
135 "Failed to join Player {} to Room ID {}. Could not add to new room.",
136 player->getId(), roomId);
141 player->setRoomId(room->getId());
143 player->setReady(
true);
146 player->setReady(
false);
150 log::info(
"Player {} (Session ID {}) joined Room ID {}",
151 player->getUsername(), player->getId(), room->getId());
155 response << static_cast<uint8_t>(1);
172 std::shared_ptr<Room> previousRoom;
174 std::lock_guard lock(
_mutex);
180 uint32_t previousRoomId = mapIt->second;
181 auto prevIt =
_rooms.find(previousRoomId);
182 if (prevIt !=
_rooms.end()) {
183 previousRoom = prevIt->second;
184 prevIt->second->removePlayer(player->getId(),
false);
186 prevIt->second->getCurrentPlayerCount() == 0) {
200 std::shared_ptr<Room> room;
203 std::lock_guard lock(
_mutex);
209 uint32_t roomId = it->second;
210 auto roomIt =
_rooms.find(roomId);
211 if (roomIt !=
_rooms.end()) {
212 room = roomIt->second;
214 for (
const auto& roomPlayer : room->getPlayers()) {
215 if (roomPlayer && roomPlayer->getId() == sessionId) {
221 roomIt->second->removePlayer(sessionId,
true);
223 roomIt->second->getCurrentPlayerCount() == 0) {
236 std::lock_guard lock(
_mutex);
237 log::info(
"Handle List Rooms request from Session ID {}", sessionId);
241 uint32_t roomCount = 0;
242 for (
const auto &[roomId, roomPtr] :
_rooms) {
244 auto roomType = roomPtr->getType();
245 log::info(
"Room ID {}: Type={} (Lobby={}, Public={}, Private={})",
246 roomId,
static_cast<int>(roomType),
257 responsePacket << roomCount;
259 for (
const auto &[roomId, roomPtr] :
_rooms) {
268 roomInfo.
roomId = roomPtr->getId();
269 std::strncpy(roomInfo.roomName, roomPtr->getName().c_str(),
270 sizeof(roomInfo.roomName) - 1);
271 roomInfo.roomName[
sizeof(roomInfo.roomName) - 1] =
'\0';
273 roomInfo.currentPlayers = roomPtr->getCurrentPlayerCount();
274 roomInfo.maxPlayers = roomPtr->getMaxPlayers();
275 roomInfo.difficulty = roomPtr->getDifficulty();
276 roomInfo.speed = roomPtr->getSpeed();
278 roomInfo.duration = roomPtr->getDurationMinutes();
279 roomInfo.seed = roomPtr->getSeed();
280 roomInfo.levelId = roomPtr->getLevelId();
281 roomInfo.roomType =
static_cast<uint8_t
>(roomPtr->getType());
283 responsePacket << roomInfo;
285 log::info(
"Listed Room ID {}: Name='{}', Players={}/{}",
286 roomInfo.roomId, roomInfo.roomName,
287 roomInfo.currentPlayers, roomInfo.maxPlayers);
292 log::info(
"Sent Room List ({} rooms) to Session ID {}", roomCount,
304 std::vector<std::shared_ptr<Room>> toStart;
307 std::lock_guard lock(
_mutex);
309 for (
auto &[roomId, roomPtr] :
_rooms) {
316 bool allReady =
true;
317 for (
const auto &player : roomPtr->getPlayers()) {
318 if (!player->isReady()) {
324 if (allReady && roomPtr->getCurrentPlayerCount() > 0) {
325 toStart.push_back(roomPtr);
330 for (
auto &roomPtr : toStart) {
331 const bool started = roomPtr->startGame(dt);
338 log::info(
"Launching Room ID {} as all players are ready.",
342 for (
const auto &player : roomPtr->getPlayers()) {
344 "Notifying Player {} (Session ID {}) of game start "
346 player->getUsername(), player->getId(),
353 "Room ID {} did NOT start (canStartGame/state blocked).",
361 std::lock_guard lock(
_mutex);
363 auto it =
_rooms.find(roomId);
371 const std::shared_ptr<Room>& room)
377 const uint32_t entityId = player->getEntityId();
391 auto &nets = netsRes->get();
393 for (
auto e : nets.entities()) {
394 if (nets[e].
id == entityId) {
409 if (transformsRes && typesRes && roomsRes) {
410 auto &transforms = transformsRes->get();
411 auto &types = typesRes->get();
412 auto &rooms = roomsRes->get();
413 if (transforms.has(entity) && types.has(entity) && nets.has(entity) && rooms.has(entity)) {
415 if (shouldBroadcast) {
416 const auto players = room->getPlayers();
417 if (!players.empty()) {
420 payload.
netId = nets[entity].id;
421 payload.type =
static_cast<uint8_t
>(types[entity].type);
422 payload.position = transforms[entity].position;
425 for (
const auto& roomPlayer : players) {
436 player->setEntityId(0);
Represents an entity in the ECS (Entity-Component-System) architecture.
constexpr bool isNull(void) const noexcept
auto get(this const Self &self) -> std::expected< std::reference_wrapper< ConstLike< Self, SparseArray< T > > >, rtp::Error >
Network packet with header and serializable body.
System to handle network-related operations on the server side.
void sendPacketToSession(uint32_t sessionId, const net::Packet &packet, net::NetworkMode mode)
Send a packet to a specific session.
void unbindSession(uint32_t sessionId)
void launchReadyRooms(float dt)
Launch all rooms that are ready to start the game.
bool joinLobby(PlayerPtr player)
Join the lobby room.
RoomSystem(ServerNetwork &network, ecs::Registry ®istry, NetworkSyncSystem &networkSync)
Constructor for RoomSystem.
ServerNetwork & _network
Reference to the server network manager.
uint32_t _nextRoomId
Next available room ID.
void disconnectPlayer(uint32_t sessionId)
Disconnect a player from all rooms.
std::mutex _mutex
Mutex for thread-safe operations.
void despawnPlayerEntity(const PlayerPtr &player, const std::shared_ptr< Room > &room)
std::shared_ptr< Room > getRoom(uint32_t roomId)
Get a room by its ID.
bool joinRoom(PlayerPtr player, uint32_t roomId, bool asSpectator=false)
Join an existing room based on client request.
RoomStartedCb _onRoomStarted
Callback for when a room starts.
void update(float dt) override
Update system logic for one frame.
uint32_t _lobbyId
ID of the main lobby room.
uint32_t createRoom(uint32_t sessionId, const std::string &roomName, uint8_t maxPlayers, float difficulty, float speed, Room::RoomType type, uint32_t levelId, uint32_t seed, uint32_t durationMinutes)
Create a new room based on client request.
NetworkSyncSystem & _networkSync
Reference to the network sync system.
std::map< uint32_t, uint32_t > _playerRoomMap
Map of player session ID to room ID.
std::map< uint32_t, std::shared_ptr< Room > > _rooms
Map of room ID to Room instances.
bool leaveRoom(PlayerPtr player)
Leave the current room based on client request.
void listAllRooms(uint32_t sessionId)
List all available rooms based on client request.
void chatInRoom(uint32_t sessionId, const net::Packet &packet)
Handle chat message in the room based on client request.
ecs::Registry & _registry
Reference to the entity registry.
PlayerType
Enum representing the type of player in the room.
@ Spectator
Spectator player.
@ InGame
Game in progress.
@ Waiting
Waiting for players.
@ Private
Private room type, hosted by the player.
@ Public
Public room type, can be joined by anyone.
@ Lobby
Lobby room type, Only used for the principal Lobby.
Implementation ASIO du serveur réseau (TCP + UDP)
void sendPacket(uint32_t sessionId, const net::Packet &packet, net::NetworkMode mode)
Send a packet to a specific session.
constexpr Entity NullEntity
void error(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log an error message.
void warning(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log a warning message.
void info(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log an informational message.
void debug(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log a debug message.
@ JoinRoom
Request to join a room.
@ RoomList
Response with room list.
@ StartGame
Notification to start the game.
@ EntityDeath
Entity death notification.
File : GameManager.hpp License: MIT Author : Elias Josué HAJJAR LLAUQUEN elias-josue....
std::shared_ptr< Player > PlayerPtr
Shared pointer type for Player.
Component representing a network identifier for an entity.
Component representing a network identifier for an entity.
Entity death notification data.
uint32_t netId
Network entity identifier.
Information about a game room Server OpCode.
uint32_t roomId
Room identifier.