/
yaseeeeechka
/
CenterControl
Обзор
Документация
Войти
/
yaseeeeechka
/
CenterControl
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
CenterControl_TCP/include/server/RoomManager.h
150 строк
5 KB
Yaroslava
New structure of Repo. TCP impl
11 дек 2025, 21:12
11 дек 2025, 21:12
6fdf9d7
Код
Авторство
О чём код?
#ifndef CENTERCONTROL_ROOMMANAGER_H #define CENTERCONTROL_ROOMMANAGER_H #include "GameManager.h" struct Room { std::string name; std::vector<std::string> players; }; class RoomsManager { public: static RoomsManager &Instance() { static RoomsManager inst; return inst; } // список всех комнат std::vector<Room> List() { std::lock_guard<std::mutex> l(m_); std::vector<Room> out; out.reserve(rooms_.size()); for (auto &[name, players]: rooms_) { out.push_back(Room{name, std::vector<std::string>(players.begin(), players.end())}); } return out; } // создать комнату bool Create(const std::string &roomName) { std::lock_guard<std::mutex> l(m_); auto rn = roomName; if (rooms_.contains(rn)) return false; // уже существует // создаём пустую комнату без участников rooms_.emplace(rn, std::unordered_set<std::string>{}); return true; } bool DeleteIfEmpty(const std::string &roomName) { std::lock_guard<std::mutex> l(m_); auto it = rooms_.find(roomName); if (it == rooms_.end()) return false; if (!it->second.empty()) return false; // есть игроки — нельзя rooms_.erase(it); // на всякий случай очищаем чат этой комнаты ChatManager::Instance().ClearRoom(roomName); return true; } bool Join(const std::string &user, const std::string &roomName) { std::lock_guard<std::mutex> l(m_); auto it = rooms_.find(roomName); if (it == rooms_.end()) return false; // комнаты нет // если уже в какой-то комнате — сперва выйдем auto uit = user_to_room_.find(user); if (uit != user_to_room_.end() && uit->second != roomName) { rooms_[uit->second].erase(user); user_to_room_.erase(uit); } it->second.insert(user); user_to_room_[user] = roomName; return true; } bool Leave(const std::string &user, const std::string &roomName) { std::lock_guard<std::mutex> l(m_); auto it = rooms_.find(roomName); if (it == rooms_.end()) return false; it->second.erase(user); auto uit = user_to_room_.find(user); if (uit != user_to_room_.end() && uit->second == roomName) { user_to_room_.erase(uit); } // 🔹 Если после выхода игрока комната пустая — чистим её чат if (it->second.empty()) { ChatManager::Instance().ClearRoom(roomName); } // Комнату по-прежнему не удаляем — только по DELETE_ROOM return true; } // вспомогательное: получить (имя комнаты -> число игроков) std::vector<RoomInfo> GetRoomInfos() { std::lock_guard<std::mutex> l(m_); std::vector<RoomInfo> out; out.reserve(rooms_.size()); for (auto &[name, players] : rooms_) { RoomInfo ri; ri.name = name; ri.players = static_cast<uint8_t>(std::min<size_t>(players.size(), 255)); // 🔹 тут спрашиваем у GameManager, есть ли активная игра ri.inGame = GameManager::Instance().HasGame(name); out.push_back(std::move(ri)); } return out; } std::vector<std::string> GetPlayers(const std::string &roomName) { std::lock_guard<std::mutex> l(m_); std::vector<std::string> out; auto it = rooms_.find(roomName); if (it == rooms_.end()) { return out; } out.reserve(it->second.size()); for (const auto &u: it->second) { out.push_back(u); } return out; } // освободить участника при завершении сессии (если в будущем добавим JOIN/LEAVE) void DetachUser(const std::string &user) { std::lock_guard<std::mutex> l(m_); auto it = user_to_room_.find(user); if (it == user_to_room_.end()) return; auto rname = it->second; user_to_room_.erase(it); auto rit = rooms_.find(rname); if (rit == rooms_.end()) return; rit->second.erase(user); if (rit->second.empty()) { // очищаем чат комнаты ChatManager::Instance().ClearRoom(rname); // и, как раньше, можем удалить саму комнату (TODO: ПРОВЕРИТЬ УДАЛЕНИЕ КОМНАТЫ!) //rooms_.erase(rit); } } private: RoomsManager() = default; std::mutex m_; std::unordered_map<std::string, std::unordered_set<std::string> > rooms_; std::unordered_map<std::string, std::string> user_to_room_; }; #endif //CENTERCONTROL_ROOMMANAGER_H