diff --git a/config/chatconfig.json b/config/chatconfig.json index ff0cc45..0ff9e6c 100644 --- a/config/chatconfig.json +++ b/config/chatconfig.json @@ -7,11 +7,27 @@ "password": "r3EMWJ5p", "connectstring": "tsschulz.de:1521/yourpart" }, + "room-types": { + 0: "Standard", + 1: "Dice possible", + 2: "Poker possible", + 4: "Room will work with rounds" + }, "rooms": [ { "name": "Halle", "password": "", - "allowed": [] + "allowed": [], + "type": 0, + "roundlength": 0 + }, + { + "name": "Würfelglück", + "password": "", + "allowed": [], + "type": 5, + "roundlength": 20 } - ] + + ], } diff --git a/room.cpp b/room.cpp index 96f16fd..cc86858 100644 --- a/room.cpp +++ b/room.cpp @@ -4,17 +4,27 @@ #include #include #include +#include +#include +#include namespace Yc { namespace Lib { - Room::Room(Server *parent, std::string name, std::string password, std::vector allowedUsers) : + Room::Room(Server *parent, Json::Value roomParams) : _parent(parent), - _name(name), - _password(password), - _allowedUsers(allowedUsers), _blocked(false), - _stop(false) { + _stop(false), + _roundRunning(false) { + _name = roomParams["name"].asString(); + _password = roomParams["password"].asString(); + std::vector 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 = new std::thread(&Room::run, this); } @@ -36,6 +46,9 @@ namespace Yc { _blocked = false; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); + if ((_type & dice) == dice) { + _handleDice(); + } } } @@ -47,12 +60,14 @@ namespace Yc { _users.push_back(newUser); newUser->sendMsg(User::roomList, _parent->jsonRoomList(), "", ""); addMessage(User::system, "room_entered", newUser->name(), newUser->color()); + _initRound(); return true; } bool Room::addUser(User *user, std::string password) { if (password == _password) { _users.push_back(user); + _initRound(); return true; } return false; @@ -80,6 +95,10 @@ namespace Yc { _stop = true; } + void Room::addMessage(User::MsgType type, const char *messageText, std::string userName, std::string color) { + addMessage(type, messageText, userName, color); + } + void Room::addMessage(User::MsgType type, std::string messageText, std::string userName, std::string color) { Message message; @@ -90,6 +109,78 @@ namespace Yc { _msgQueue.push(message); } + void Room::addMessage(User::MsgType type, Json::Value messageText, std::string userName, std::string color) { + addMessage(type, getJsonString(messageText), userName, color); + } + + Room::RoomType Room::type() { + return _type; + } + + bool Room::isType(Room::RoomType type) { + return ((_type & type) == type); + } + + bool Room::canDice() { + return (_roundRunning || (_type & rounds) == rounds) && (_type & dice) == dice; + } + + unsigned int Room::addDice(User *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(User::dice, std::to_string(diceValue), user->name(), user->color()); + return 0; + + } + + bool Room::accessAllowed(std::string userName, std::string password) { + return (_allowedUsers.size() == 0 || _password == "" || _password == password || std::find(_allowedUsers.begin(), _allowedUsers.end(), userName) != _allowedUsers.end()); + } + + void Room::_handleDice() { + if (((_type & rounds) == rounds)) { + if ((_users.size() < 2 && _roundRunning) || (!_roundRunning && _roundStart + _roundLength >= time(NULL))) { + _lastRoundEnd = time(NULL); + _roundRunning = false; + addMessage(User::system, "round_ends"); + _showDiceRoundResults(); + } else if (!_roundRunning && _lastRoundEnd <= time(NULL) - 15) { + _roundStart = time(NULL); + _roundRunning = true; + _diceValues.clear(); + addMessage(User::system, "next_round_starts_now"); + } + } + } + + void Room::_initRound() { + if (_users.size() == 2) { + _lastRoundEnd = time(NULL); + addMessage(User::system, "next_round_starts_soon"); + } + } + + void Room::_showDiceRoundResults() { + std::sort(_diceValues.begin(), _diceValues.end(), [=](std::pair val1, std::pair val2) { + return (val1.second > val2.second); + }); + Json::Value userList = Json::arrayValue; + for (auto &user: _diceValues) { + Json::Value entry = Json::objectValue; + entry["name"] = user.first; + entry["value"] = user.second; + userList.append(entry); + } + addMessage(User::result, userList); + } + std::string Room::name() { return _name; } diff --git a/room.h b/room.h index 6c928cf..f4e293a 100644 --- a/room.h +++ b/room.h @@ -6,16 +6,26 @@ #include #include #include +#include +#include +#include +#include namespace Yc { namespace Lib { class Server; - class Room - { + class Room: public Base { public: - Room(Server *parent, std::string name, std::string password = "", std::vector allowedUsers = std::vector()); + enum RoomType { + none = 0, + dice = 1, + poker = 2, + rounds = 4 + }; + + Room(Server *parent, Json::Value roomParams); ~Room(); void run(); std::string name(); @@ -24,7 +34,14 @@ namespace Yc { bool userNameExists(std::string userName); void removeUser(std::string _token); void setStop(); - void addMessage(User::MsgType type, std::string message, std::string userName = "", std::string color = ""); + void addMessage(User::MsgType type, const char* messageText, std::string userName = "", std::string color = ""); + void addMessage(User::MsgType type, std::string messageText, std::string userName = "", std::string color = ""); + void addMessage(User::MsgType type, Json::Value messageText, std::string userName = "", std::string color = ""); + RoomType type(); + bool isType(RoomType type); + bool canDice(); + unsigned int addDice(User *user, int diceValue); + bool accessAllowed(std::string userName, std::string password); private: struct Message { User::MsgType type; @@ -37,11 +54,22 @@ namespace Yc { std::string _name; std::string _password; std::vector _allowedUsers; + RoomType _type; std::vector _users; bool _blocked; bool _stop; std::queue _msgQueue; std::thread *thread; + bool _roundRunning; + time_t _roundStart; + time_t _lastRoundEnd; + int _roundLength; + std::vector> _diceValues; + void _handleDice(); + void _startDiceRound(); + void _endDiceRound(); + void _initRound(); + void _showDiceRoundResults(); }; } // namespace Lib diff --git a/server.cpp b/server.cpp index 11962db..9738850 100644 --- a/server.cpp +++ b/server.cpp @@ -70,13 +70,18 @@ namespace Yc { return list; } + bool Server::roomAllowed(std::string roomName, std::string userName, std::string password){ + for (auto &room: _rooms) { + if (room->name() == roomName && room->accessAllowed(userName, password)) { + return true; + } + } + return false; + } + void Server::createRooms(Json::Value roomList) { for (auto &room: roomList) { - std::vector allowedUsers; - for (auto &user: room["allowed"]) { - allowedUsers.push_back(user.asString()); - } - Room *newRoom = new Room(this, room["name"].asString(), room["password"].asString(), allowedUsers); + Room *newRoom = new Room(this, room); _rooms.push_back(newRoom); } } diff --git a/server.h b/server.h index 6504314..7dec82a 100644 --- a/server.h +++ b/server.h @@ -17,6 +17,7 @@ namespace Yc { void run(); std::vector roomList(); Json::Value jsonRoomList(); + bool roomAllowed(std::string roomName, std::string userName, std::string password); private: int _socket; Yc::Lib::Config *_config; diff --git a/user.cpp b/user.cpp index 0db60c7..21feb8a 100644 --- a/user.cpp +++ b/user.cpp @@ -27,7 +27,7 @@ namespace Yc { User::~User() { delete thread; - _parent->addMessage(User::system, "leaved_chat", _name, _color); + _parent->addMessage(User::system, std::string("leaved_chat"), _name, _color); } std::string User::name() const { @@ -42,6 +42,10 @@ namespace Yc { return (toValidate == 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; @@ -103,6 +107,25 @@ namespace Yc { Json::Value jsonTree = getJsonTree(message); if (jsonTree["type"].asString() == "message") { _parent->addMessage(User::message, jsonTree["message"].asString(), _name, _color); + } 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); + } + } + + void User::doDice() { + switch (_parent->addDice(this, (rand() % 6) + 1)) { + case 1: + sendMsg(system, "dice_not_possible", "", ""); + break; + case 2: + sendMsg(system, "dice_allready_done", "", ""); + break; + default: + break; } } } // namespace Lib diff --git a/user.h b/user.h index 30ddcb2..97fa154 100644 --- a/user.h +++ b/user.h @@ -19,7 +19,11 @@ namespace Yc { userListe = 2, roomList = 3, message = 4, - system = 5 + system = 5, + scream = 6, + dosomething = 7, + dice = 8, + result = 9 }; User(Room *parent, std::string name, std::string color, int socket); @@ -28,6 +32,7 @@ namespace Yc { bool validateToken(std::string token); bool isUser(User *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(); @@ -43,6 +48,7 @@ namespace Yc { void send(std::string out); void send(Json::Value out); void handleMessage(std::string message); + void doDice(); }; } // namespace Lib