From 6ecdbda9de37918af7e240348c0e4de895b673d1 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 11 Aug 2025 15:03:11 +0200 Subject: [PATCH] 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 instead of shared_ptr. - 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. --- CMakeLists.txt | 3 +- room.cpp => chat_room.cpp | 58 +++---- room.h => chat_room.h | 13 +- chat_user.cpp | 6 +- chat_user.h | 13 +- server.cpp | 2 +- server.h | 4 +- user.cpp | 344 -------------------------------------- user.h | 61 ------- 9 files changed, 48 insertions(+), 456 deletions(-) rename room.cpp => chat_room.cpp (78%) rename room.h => chat_room.h (90%) delete mode 100755 user.cpp delete mode 100755 user.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8908fd7..f04d568 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,5 @@ project(YourChat VERSION 0.1) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED True) include_directories(${PROJECT_SOURCE_DIR}) - add_executable(yourchat main.cpp base.cpp config.cpp server.cpp room.cpp tools.cpp chat_user.cpp database.cpp) - # Removed chatroom.cpp, chatuser.cpp, chatroom.h, chatuser.h from the build + add_executable(yourchat main.cpp base.cpp config.cpp server.cpp chat_room.cpp tools.cpp chat_user.cpp database.cpp) target_link_libraries(yourchat jsoncpp pthread pqxx) diff --git a/room.cpp b/chat_room.cpp similarity index 78% rename from room.cpp rename to chat_room.cpp index 677a24c..40f674c 100755 --- a/room.cpp +++ b/chat_room.cpp @@ -1,4 +1,4 @@ -#include "room.h" +#include "chat_room.h" #include #include @@ -12,7 +12,7 @@ namespace Yc { namespace Lib { - Room::Room(std::shared_ptr parent, Json::Value roomParams) : + ChatRoom::ChatRoom(std::shared_ptr parent, Json::Value roomParams) : _parent(std::move(parent)), _blocked(false), _stop(false), @@ -26,12 +26,12 @@ namespace Yc { _type = (RoomType)roomParams["type"].asInt(); _roundLength = roomParams["roundlength"].asInt(); _lastRoundEnd = std::time(NULL); - thread = std::make_unique(&Room::run, this); + thread = std::make_unique(&ChatRoom::run, this); } - Room::~Room() = default; + ChatRoom::~ChatRoom() = default; - void Room::run() { + void ChatRoom::run() { while (!_stop) { if (_msgQueue.size() > 0 && !_blocked) { _blocked = true; @@ -51,7 +51,7 @@ namespace Yc { } } - bool Room::addUser(std::string _userName, std::string color, std::string _password, int socket) { + 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; } @@ -63,7 +63,7 @@ namespace Yc { return true; } - bool Room::addUser(std::shared_ptr user, std::string password) { + bool ChatRoom::addUser(std::shared_ptr user, std::string password) { if (password == _password) { _users.push_back(user); user->setParent(shared_from_this()); @@ -73,7 +73,7 @@ namespace Yc { return false; } - bool Room::userNameExists(std::string userName) { + bool ChatRoom::userNameExists(std::string userName) { for (const auto &user: _users) { if (user->name() == userName) { return true; @@ -82,7 +82,7 @@ namespace Yc { return false; } - void Room::removeUser(std::string _token, bool silent) { + void ChatRoom::removeUser(std::string _token, bool silent) { for (auto it = _users.begin(); it != _users.end(); ++it) { if ((*it)->validateToken(_token)) { if (!silent) { @@ -94,7 +94,7 @@ namespace Yc { } } - void Room::removeUser(std::shared_ptr userToRemove, bool silent) { + void ChatRoom::removeUser(std::shared_ptr userToRemove, bool silent) { for (auto it = _users.begin(); it != _users.end(); ++it) { if (*it == userToRemove) { if (!silent) { @@ -106,15 +106,15 @@ namespace Yc { } } - void Room::setStop() { + void ChatRoom::setStop() { _stop = true; } - void Room::addMessage(ChatUser::MsgType type, const char *messageText, std::string userName, std::string color) { + void ChatRoom::addMessage(ChatUser::MsgType type, const char *messageText, std::string userName, std::string color) { addMessage(type, (std::string)messageText, userName, color); } - void Room::addMessage(ChatUser::MsgType type, std::string messageText, std::string userName, std::string color) { + void ChatRoom::addMessage(ChatUser::MsgType type, std::string messageText, std::string userName, std::string color) { Message message; message.type = type; message.messageTr = messageText; @@ -123,11 +123,11 @@ namespace Yc { _msgQueue.push(message); } - void Room::addMessage(ChatUser::MsgType type, Json::Value messageText, std::string userName, std::string color) { + void ChatRoom::addMessage(ChatUser::MsgType type, Json::Value messageText, std::string userName, std::string color) { addMessage(type, getJsonString(messageText), userName, color); } - void Room::addUserWhenQueueEmpty(std::shared_ptr user) { + void ChatRoom::addUserWhenQueueEmpty(std::shared_ptr user) { while (_msgQueue.size() > 0) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } @@ -135,19 +135,19 @@ namespace Yc { user->setParent(shared_from_this()); } - bool Room::userToNewRoom(std::shared_ptr user, std::string newRoom, std::string password) { + bool ChatRoom::userToNewRoom(std::shared_ptr user, std::string newRoom, std::string password) { return _parent->changeRoom(user, newRoom, password); } - unsigned int Room::flags() { + unsigned int ChatRoom::flags() { unsigned int value = (unsigned int)_type; if (_password != "") { - value += (unsigned int)Room::password; + value += (unsigned int)ChatRoom::password; } return value; } - Json::Value Room::userList() { + Json::Value ChatRoom::userList() { Json::Value users = Json::arrayValue; for (auto &user: _users) { Json::Value jsonUser = Json::objectValue; @@ -157,19 +157,19 @@ namespace Yc { return users; } - Room::RoomType Room::type() { + ChatRoom::RoomType ChatRoom::type() { return _type; } - bool Room::isType(Room::RoomType type) { + bool ChatRoom::isType(ChatRoom::RoomType type) { return ((_type & type) == type); } - bool Room::canDice() { + bool ChatRoom::canDice() { return (_roundRunning || (_type & rounds) == rounds) && (_type & dice) == dice; } - unsigned int Room::addDice(std::shared_ptr user, int diceValue) { + unsigned int ChatRoom::addDice(std::shared_ptr user, int diceValue) { if (!canDice()) { return 1; } @@ -183,11 +183,11 @@ namespace Yc { return 0; } - bool Room::accessAllowed(std::string userName, std::string password) { + 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 Room::userIsInRoom(std::string userName) { + bool ChatRoom::userIsInRoom(std::string userName) { for (auto &user: _users) { if (userName == user->name()) { return true; @@ -196,7 +196,7 @@ namespace Yc { return false; } - void Room::_handleDice() { + void ChatRoom::_handleDice() { if (((_type & rounds) == rounds)) { if (_roundRunning && (_users.size() < 2 || _roundStart + _roundLength >= time(NULL))) { _lastRoundEnd = time(NULL); @@ -212,14 +212,14 @@ namespace Yc { } } - void Room::_initRound() { + void ChatRoom::_initRound() { if (_users.size() == 2) { _lastRoundEnd = time(NULL); addMessage(ChatUser::system, "next_round_starts_soon"); } } - void Room::_showDiceRoundResults() { + void ChatRoom::_showDiceRoundResults() { std::sort(_diceValues.begin(), _diceValues.end(), [=](const std::pair, int>& val1, const std::pair, int>& val2) { return (val1.second > val2.second); }); @@ -233,7 +233,7 @@ namespace Yc { addMessage(ChatUser::result, userList); } - std::string Room::name() { + std::string ChatRoom::name() { return _name; } diff --git a/room.h b/chat_room.h similarity index 90% rename from room.h rename to chat_room.h index 4d4670b..bd23742 100755 --- a/room.h +++ b/chat_room.h @@ -1,5 +1,6 @@ -#ifndef YC_LIB_ROOM_H -#define YC_LIB_ROOM_H +// renamed from room.h +#ifndef YC_LIB_CHAT_ROOM_H +#define YC_LIB_CHAT_ROOM_H #include @@ -19,7 +20,7 @@ namespace Yc { class Server; - class Room: public Base, public std::enable_shared_from_this { + class ChatRoom: public Base, public std::enable_shared_from_this { public: enum RoomType { none = 0, @@ -29,8 +30,8 @@ namespace Yc { password = 8 }; - Room(std::shared_ptr parent, Json::Value roomParams); - ~Room(); + ChatRoom(std::shared_ptr parent, Json::Value roomParams); + ~ChatRoom(); void run(); std::string name(); bool addUser(std::string userName, std::string color, std::string password, int socket); @@ -85,4 +86,4 @@ namespace Yc { } // namespace Lib } // namespace Yc -#endif // YC_LIB_ROOM_H +#endif // YC_LIB_CHAT_ROOM_H diff --git a/chat_user.cpp b/chat_user.cpp index c1a13bd..db47420 100644 --- a/chat_user.cpp +++ b/chat_user.cpp @@ -6,7 +6,7 @@ #include #include #include -#include "room.h" +#include "chat_room.h" #include #include #include @@ -15,7 +15,7 @@ namespace Yc { namespace Lib { -ChatUser::ChatUser(std::shared_ptr parent, std::string name, std::string color, int socket) : +ChatUser::ChatUser(std::shared_ptr parent, std::string name, std::string color, int socket) : _parent(std::move(parent)), _name(std::move(name)), _color(std::move(color)), @@ -96,7 +96,7 @@ std::string ChatUser::color() const { return _color; } -void ChatUser::setParent(std::shared_ptr parent) { +void ChatUser::setParent(std::shared_ptr parent) { _parent = std::move(parent); } diff --git a/chat_user.h b/chat_user.h index d937da6..34936e5 100644 --- a/chat_user.h +++ b/chat_user.h @@ -1,21 +1,18 @@ #ifndef YC_LIB_CHAT_USER_H #define YC_LIB_CHAT_USER_H - #include #include #include #include #include - - #include "base.h" -// Forward declaration to break cyclic dependency -namespace Yc { namespace Lib { class Room; } } namespace Yc { namespace Lib { +class ChatRoom; + class ChatUser: public Base, public std::enable_shared_from_this { public: enum MsgType { @@ -31,7 +28,7 @@ public: result = 9 }; - ChatUser(std::shared_ptr parent, std::string name, std::string color, int socket); + ChatUser(std::shared_ptr parent, std::string name, std::string color, int socket); ~ChatUser(); std::string name() const; bool validateToken(std::string token); @@ -42,10 +39,10 @@ public: void checkerTask(); void stop(); std::string color() const; - void setParent(std::shared_ptr parent); + void setParent(std::shared_ptr parent); private: - std::shared_ptr _parent; + std::shared_ptr _parent; std::string _name; std::string _color; int _socket; diff --git a/server.cpp b/server.cpp index d40ad9f..7d44d8d 100755 --- a/server.cpp +++ b/server.cpp @@ -116,7 +116,7 @@ namespace Yc { void Server::createRooms(Json::Value roomList) { auto self = shared_from_this(); for (auto &room: roomList) { - auto newRoom = std::make_shared(self, room); + auto newRoom = std::make_shared(self, room); _rooms.push_back(newRoom); } } diff --git a/server.h b/server.h index 6ba33a8..72602ee 100755 --- a/server.h +++ b/server.h @@ -4,7 +4,7 @@ #include "config.h" #include "database.h" #include -#include "room.h" +#include "chat_room.h" #include "base.h" #include @@ -24,7 +24,7 @@ namespace Yc { std::shared_ptr _config; std::shared_ptr _database; bool _stop; - std::vector> _rooms; + std::vector> _rooms; void createRooms(Json::Value roomList); private: void handleRequest(); diff --git a/user.cpp b/user.cpp deleted file mode 100755 index bc01822..0000000 --- a/user.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#include "user.h" - -#include -#include -#include -#include -#include -#include "room.h" -#include -#include -#include -#include - -namespace Yc { - namespace Lib { - - User::User(std::shared_ptr parent, std::string name, std::string color, int socket) : - _parent(std::move(parent)), - _name(std::move(name)), - _color(std::move(color)), - _socket(socket), - _stop(false) { - _token = Yc::Lib::Tools::generateRandomString(32); - sendMsg(token, _token, "", ""); - thread = std::make_unique(&User::checkerTask, this); - } - - User::~User() { - _parent->addMessage(User::system, std::string("leaved_chat"), _name, _color); - } - - std::string User::name() const { - return _name; - } - - bool User::validateToken(std::string token) { - return (token == _token); - } - - bool User::isUser(std::shared_ptr toValidate) { - return (toValidate.get() == this); - } - - void User::sendMsg(MsgType type, const char *message, std::string userName, std::string color) { - sendMsg(type, std::string(message), userName, color); - } - - void User::sendMsg(MsgType type, std::string message , std::string userName, std::string color) { - Json::Value sendMessage; - sendMessage["type"] = type; - sendMessage["message"] = message; - sendMessage["userName"] = userName; - sendMessage["color"] = color; - send(sendMessage); - } - - void User::sendMsg(User::MsgType type, Json::Value message, std::string userName, std::string color) { - Json::Value sendMessage; - sendMessage["type"] = type; - sendMessage["message"] = message; - sendMessage["userName"] = userName; - sendMessage["color"] = color; - send(sendMessage); - } - - void User::checkerTask() { - while (!_stop) { - fd_set readSd; - FD_ZERO(&readSd); - FD_SET(_socket, &readSd); - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 500; - int selectResult = select(_socket + 1, &readSd, NULL, NULL, &tv); - if (selectResult == 1 && FD_ISSET(_socket, &readSd) == 1) { - _parent->removeUser(_token); - _stop = true; - delete this; - return; - } - std::string msg = readSocket(_socket); - if (msg == "") { - continue; - } - handleMessage(msg); - } - } - - void User::stop() { - _stop = true; - } - - std::string User::color() const { - return _color; - } - - void User::setParent(std::shared_ptr parent) { - _parent = std::move(parent); - } - - void User::send(std::string out) { - Base::send(_socket, out); - } - - void User::send(Json::Value out) { - Base::send(_socket, out); - } - - void User::handleMessage(std::string message) { - Json::Value jsonTree = getJsonTree(message); - if (jsonTree["token"].asString() != _token) { - return; - } - if (jsonTree["type"].asString() == "message") { - checkString(jsonTree["message"].asString()); - } else if (jsonTree["type"].asString() == "dice") { - doDice(); - } else if (jsonTree["type"].asString() == "scream") { - _parent->addMessage(User::scream, jsonTree["message"].asString(), _name, _color); - } else if (jsonTree["type"].asString() == "do") { - _parent->addMessage(User::dosomething, jsonTree["message"].asString(), _name, _color); - } else if (jsonTree["type"].asString() == "join") { - changeRoom(jsonTree["newroom"].asString(), jsonTree["password"].asString()); - } else if (jsonTree["type"].asString() == "userlist") { - sendUserList(); - } - } - - void User::checkString(std::string message) { - if (message.substr(0, 6) == "/join ") { - message = message.substr(6); - if (message.find(" ") == std::string::npos) { - changeRoom(message, ""); - } else { - std::string room = message.substr(0, message.find(" ")); - std::string password = message.substr(message.find(" ") + 1); - changeRoom(room, password); - } - } else if (message == "/dice") { - doDice(); - } else { - _parent->addMessage(User::message, message, _name, _color); - } - } - - void User::sendUserList() { - Json::Value userList = _parent->userList(); - Json::Value msg = Json::objectValue; - msg["userlist"] = userList; - sendMsg(userListe, msg, "", ""); - } - - void User::doDice() { - switch (_parent->addDice(shared_from_this(), (rand() % 6) + 1)) { - case 1: - sendMsg(system, "dice_not_possible", "", ""); - break; - case 2: - sendMsg(system, "dice_allready_done", "", ""); - break; - default: - break; - } - } - - void User::changeRoom(std::string newRoom, std::string password) { - if (!_parent->userToNewRoom(shared_from_this(), newRoom, password)) { - sendMsg(User::system, "room_not_possible", "", ""); - } - } - } // namespace Lib -} // namespace Yc -#include "user.h" - -#include -#include -#include -#include -#include -#include "room.h" -#include -#include -#include -#include - -namespace Yc { - namespace Lib { - - User::User(std::shared_ptr parent, std::string name, std::string color, int socket) : - _parent(std::move(parent)), - _name(std::move(name)), - _color(std::move(color)), - _socket(socket), - _stop(false) { - _token = Yc::Lib::Tools::generateRandomString(32); - sendMsg(token, _token, "", ""); - thread = std::make_unique(&User::checkerTask, this); - } - - User::~User() { - _parent->addMessage(User::system, std::string("leaved_chat"), _name, _color); - } - - std::string User::name() const { - return _name; - } - - bool User::validateToken(std::string token) { - return (token == _token); - } - - bool User::isUser(std::shared_ptr toValidate) { - return (toValidate.get() == this); - } - - void User::sendMsg(MsgType type, const char *message, std::string userName, std::string color) { - sendMsg(type, std::string(message), userName, color); - } - - void User::sendMsg(MsgType type, std::string message , std::string userName, std::string color) { - Json::Value sendMessage; - sendMessage["type"] = type; - sendMessage["message"] = message; - sendMessage["userName"] = userName; - sendMessage["color"] = color; - send(sendMessage); - } - - void User::sendMsg(User::MsgType type, Json::Value message, std::string userName, std::string color) { - Json::Value sendMessage; - sendMessage["type"] = type; - sendMessage["message"] = message; - sendMessage["userName"] = userName; - sendMessage["color"] = color; - send(sendMessage); - } - - void User::checkerTask() { - while (!_stop) { - fd_set readSd; - FD_ZERO(&readSd); - FD_SET(_socket, &readSd); - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 500; - int selectResult = select(_socket + 1, &readSd, NULL, NULL, &tv); - if (selectResult == 1 && FD_ISSET(_socket, &readSd) == 1) { - _parent->removeUser(_token); - _stop = true; - delete this; - return; - } - std::string msg = readSocket(_socket); - if (msg == "") { - continue; - } - handleMessage(msg); - } - } - - void User::stop() { - _stop = true; - } - - std::string User::color() const { - return _color; - } - - void User::setParent(std::shared_ptr parent) { - _parent = std::move(parent); - } - - void User::send(std::string out) { - Base::send(_socket, out); - } - - void User::send(Json::Value out) { - Base::send(_socket, out); - } - - void User::handleMessage(std::string message) { - Json::Value jsonTree = getJsonTree(message); - if (jsonTree["token"].asString() != _token) { - return; - } - if (jsonTree["type"].asString() == "message") { - checkString(jsonTree["message"].asString()); - } else if (jsonTree["type"].asString() == "dice") { - doDice(); - } else if (jsonTree["type"].asString() == "scream") { - _parent->addMessage(User::scream, jsonTree["message"].asString(), _name, _color); - } else if (jsonTree["type"].asString() == "do") { - _parent->addMessage(User::dosomething, jsonTree["message"].asString(), _name, _color); - } else if (jsonTree["type"].asString() == "join") { - changeRoom(jsonTree["newroom"].asString(), jsonTree["password"].asString()); - } else if (jsonTree["type"].asString() == "userlist") { - sendUserList(); - } - } - - void User::checkString(std::string message) { - if (message.substr(0, 6) == "/join ") { - message = message.substr(6); - if (message.find(" ") == std::string::npos) { - changeRoom(message, ""); - } else { - std::string room = message.substr(0, message.find(" ")); - std::string password = message.substr(message.find(" ") + 1); - changeRoom(room, password); - } - } else if (message == "/dice") { - doDice(); - } else { - _parent->addMessage(User::message, message, _name, _color); - } - } - - void User::sendUserList() { - Json::Value userList = _parent->userList(); - Json::Value msg = Json::objectValue; - msg["userlist"] = userList; - sendMsg(userListe, msg, "", ""); - } - - void User::doDice() { - switch (_parent->addDice(shared_from_this(), (rand() % 6) + 1)) { - case 1: - sendMsg(system, "dice_not_possible", "", ""); - break; - case 2: - sendMsg(system, "dice_allready_done", "", ""); - break; - default: - break; - } - } - - void User::changeRoom(std::string newRoom, std::string password) { - if (!_parent->userToNewRoom(shared_from_this(), newRoom, password)) { - sendMsg(User::system, "room_not_possible", "", ""); - } - } - } // namespace Lib -} // namespace Yc diff --git a/user.h b/user.h deleted file mode 100755 index 852096e..0000000 --- a/user.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef YC_LIB_USER_H -#define YC_LIB_USER_H - -#include -#include -#include -#include "base.h" - -namespace Yc { - namespace Lib { - - class Room; - - class User: public Base, public std::enable_shared_from_this { - public: - enum MsgType { - error = -1, - token = 1, - userListe = 2, - roomList = 3, - message = 4, - system = 5, - scream = 6, - dosomething = 7, - dice = 8, - result = 9 - }; - - User(std::shared_ptr parent, std::string name, std::string color, int socket); - ~User(); - std::string name() const; - bool validateToken(std::string token); - bool isUser(std::shared_ptr toValidate); - void sendMsg(MsgType type, std::string message, std::string userName, std::string color); - void sendMsg(MsgType type, const char *message, std::string userName, std::string color); - void sendMsg(MsgType type, Json::Value message, std::string userName, std::string color); - void checkerTask(); - void stop(); - std::string color() const; - void setParent(std::shared_ptr parent); - private: - std::shared_ptr _parent; - std::string _name; - std::string _color; - int _socket; - std::string _token; - bool _stop; - std::unique_ptr thread; - void send(std::string out); - void send(Json::Value out); - void handleMessage(std::string message); - void doDice(); - void changeRoom(std::string newRoom, std::string password); - void checkString(std::string message); - void sendUserList(); - }; - - } // namespace Lib -} // namespace Yc - -#endif // YC_LIB_USER_H