Refactor chat room implementation

- Renamed Room class to ChatRoom and updated all references accordingly.
- Removed the old room.cpp and room.h files.
- Updated CMakeLists.txt to include chat_room.cpp instead of room.cpp.
- Modified ChatUser class to use shared_ptr<ChatRoom> instead of shared_ptr<Room>.
- Updated Server class to create instances of ChatRoom instead of Room.
- Removed User class and its associated files, integrating its functionality into ChatUser.
- Ensured all relevant includes and dependencies are updated to reflect the new class structure.
This commit is contained in:
Torsten Schulz (local)
2025-08-11 15:03:11 +02:00
parent b81f2de10f
commit 6ecdbda9de
9 changed files with 48 additions and 456 deletions

241
chat_room.cpp Executable file
View File

@@ -0,0 +1,241 @@
#include "chat_room.h"
#include <algorithm>
#include <server.h>
#include <unistd.h>
#include <iostream>
#include <time.h>
#include <algorithm>
#include <utility>
#include <thread>
namespace Yc {
namespace Lib {
ChatRoom::ChatRoom(std::shared_ptr<Server> parent, Json::Value roomParams) :
_parent(std::move(parent)),
_blocked(false),
_stop(false),
_roundRunning(false) {
_name = roomParams["name"].asString();
_password = roomParams["password"].asString();
std::vector<std::string> allowedUsers;
for (auto &user: roomParams["allowed"]) {
_allowedUsers.push_back(user.asString());
}
_type = (RoomType)roomParams["type"].asInt();
_roundLength = roomParams["roundlength"].asInt();
_lastRoundEnd = std::time(NULL);
thread = std::make_unique<std::thread>(&ChatRoom::run, this);
}
ChatRoom::~ChatRoom() = default;
void ChatRoom::run() {
while (!_stop) {
if (_msgQueue.size() > 0 && !_blocked) {
_blocked = true;
while (_msgQueue.size() > 0) {
Message message = _msgQueue.front();
for (auto &user: _users) {
user->sendMsg(message.type, message.messageTr, message.userName, message.color);
}
_msgQueue.pop();
}
_blocked = false;
}
if ((_type & dice) == dice) {
_handleDice();
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
bool ChatRoom::addUser(std::string _userName, std::string color, std::string _password, int socket) {
if (_password != "" && _password == _password && std::find(std::begin(_allowedUsers), std::end(_allowedUsers), _userName) == std::end(_allowedUsers)) {
return false;
}
auto newUser = std::make_shared<ChatUser>(shared_from_this(), _userName, color, socket);
_users.push_back(newUser);
newUser->sendMsg(ChatUser::roomList, _parent->jsonRoomList(), "", "");
addMessage(ChatUser::system, "room_entered", newUser->name(), newUser->color());
_initRound();
return true;
}
bool ChatRoom::addUser(std::shared_ptr<ChatUser> user, std::string password) {
if (password == _password) {
_users.push_back(user);
user->setParent(shared_from_this());
_initRound();
return true;
}
return false;
}
bool ChatRoom::userNameExists(std::string userName) {
for (const auto &user: _users) {
if (user->name() == userName) {
return true;
}
}
return false;
}
void ChatRoom::removeUser(std::string _token, bool silent) {
for (auto it = _users.begin(); it != _users.end(); ++it) {
if ((*it)->validateToken(_token)) {
if (!silent) {
addMessage(ChatUser::system, (*it)->name(), (*it)->color());
}
_users.erase(it);
break;
}
}
}
void ChatRoom::removeUser(std::shared_ptr<ChatUser> userToRemove, bool silent) {
for (auto it = _users.begin(); it != _users.end(); ++it) {
if (*it == userToRemove) {
if (!silent) {
addMessage(ChatUser::system, (*it)->name(), (*it)->color());
}
_users.erase(it);
break;
}
}
}
void ChatRoom::setStop() {
_stop = true;
}
void ChatRoom::addMessage(ChatUser::MsgType type, const char *messageText, std::string userName, std::string color) {
addMessage(type, (std::string)messageText, userName, color);
}
void ChatRoom::addMessage(ChatUser::MsgType type, std::string messageText, std::string userName, std::string color) {
Message message;
message.type = type;
message.messageTr = messageText;
message.userName = userName;
message.color = color;
_msgQueue.push(message);
}
void ChatRoom::addMessage(ChatUser::MsgType type, Json::Value messageText, std::string userName, std::string color) {
addMessage(type, getJsonString(messageText), userName, color);
}
void ChatRoom::addUserWhenQueueEmpty(std::shared_ptr<ChatUser> user) {
while (_msgQueue.size() > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
_users.push_back(user);
user->setParent(shared_from_this());
}
bool ChatRoom::userToNewRoom(std::shared_ptr<ChatUser> user, std::string newRoom, std::string password) {
return _parent->changeRoom(user, newRoom, password);
}
unsigned int ChatRoom::flags() {
unsigned int value = (unsigned int)_type;
if (_password != "") {
value += (unsigned int)ChatRoom::password;
}
return value;
}
Json::Value ChatRoom::userList() {
Json::Value users = Json::arrayValue;
for (auto &user: _users) {
Json::Value jsonUser = Json::objectValue;
jsonUser["name"] = user->name();
users.append(jsonUser);
}
return users;
}
ChatRoom::RoomType ChatRoom::type() {
return _type;
}
bool ChatRoom::isType(ChatRoom::RoomType type) {
return ((_type & type) == type);
}
bool ChatRoom::canDice() {
return (_roundRunning || (_type & rounds) == rounds) && (_type & dice) == dice;
}
unsigned int ChatRoom::addDice(std::shared_ptr<ChatUser> user, int diceValue) {
if (!canDice()) {
return 1;
}
for (auto &listUser: _diceValues) {
if (listUser.first == user) {
return 2;
}
}
_diceValues.push_back(std::make_pair(user, diceValue));
addMessage(ChatUser::dice, std::to_string(diceValue), user->name(), user->color());
return 0;
}
bool ChatRoom::accessAllowed(std::string userName, std::string password) {
return (_allowedUsers.size() == 0 || _password == "" || _password == password || std::find(_allowedUsers.begin(), _allowedUsers.end(), userName) != _allowedUsers.end());
}
bool ChatRoom::userIsInRoom(std::string userName) {
for (auto &user: _users) {
if (userName == user->name()) {
return true;
}
}
return false;
}
void ChatRoom::_handleDice() {
if (((_type & rounds) == rounds)) {
if (_roundRunning && (_users.size() < 2 || _roundStart + _roundLength >= time(NULL))) {
_lastRoundEnd = time(NULL);
_roundRunning = false;
addMessage(ChatUser::system, "round_ends");
_showDiceRoundResults();
} else if (!_roundRunning && _lastRoundEnd <= time(NULL) - 15 && _users.size() >= 2) {
_roundStart = time(NULL);
_roundRunning = true;
_diceValues.clear();
addMessage(ChatUser::system, "next_round_starts_now");
}
}
}
void ChatRoom::_initRound() {
if (_users.size() == 2) {
_lastRoundEnd = time(NULL);
addMessage(ChatUser::system, "next_round_starts_soon");
}
}
void ChatRoom::_showDiceRoundResults() {
std::sort(_diceValues.begin(), _diceValues.end(), [=](const std::pair<std::shared_ptr<ChatUser>, int>& val1, const std::pair<std::shared_ptr<ChatUser>, int>& val2) {
return (val1.second > val2.second);
});
Json::Value userList = Json::arrayValue;
for (auto &user: _diceValues) {
Json::Value entry = Json::objectValue;
entry["name"] = user.first->name();
entry["value"] = user.second;
userList.append(entry);
}
addMessage(ChatUser::result, userList);
}
std::string ChatRoom::name() {
return _name;
}
} // namespace Lib
} // namespace Yc