Added dice, added check for room access

This commit is contained in:
Torsten Schulz
2017-07-22 22:24:38 +02:00
parent b5b4c94f65
commit 105232a9e3
7 changed files with 188 additions and 18 deletions

View File

@@ -7,11 +7,27 @@
"password": "r3EMWJ5p", "password": "r3EMWJ5p",
"connectstring": "tsschulz.de:1521/yourpart" "connectstring": "tsschulz.de:1521/yourpart"
}, },
"room-types": {
0: "Standard",
1: "Dice possible",
2: "Poker possible",
4: "Room will work with rounds"
},
"rooms": [ "rooms": [
{ {
"name": "Halle", "name": "Halle",
"password": "", "password": "",
"allowed": [] "allowed": [],
"type": 0,
"roundlength": 0
},
{
"name": "Würfelglück",
"password": "",
"allowed": [],
"type": 5,
"roundlength": 20
} }
]
],
} }

101
room.cpp
View File

@@ -4,17 +4,27 @@
#include <server.h> #include <server.h>
#include <unistd.h> #include <unistd.h>
#include <iostream> #include <iostream>
#include <time.h>
#include <algorithm>
#include <utility>
namespace Yc { namespace Yc {
namespace Lib { namespace Lib {
Room::Room(Server *parent, std::string name, std::string password, std::vector<std::string> allowedUsers) : Room::Room(Server *parent, Json::Value roomParams) :
_parent(parent), _parent(parent),
_name(name),
_password(password),
_allowedUsers(allowedUsers),
_blocked(false), _blocked(false),
_stop(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 = new std::thread(&Room::run, this); thread = new std::thread(&Room::run, this);
} }
@@ -36,6 +46,9 @@ namespace Yc {
_blocked = false; _blocked = false;
} }
std::this_thread::sleep_for(std::chrono::milliseconds(50)); std::this_thread::sleep_for(std::chrono::milliseconds(50));
if ((_type & dice) == dice) {
_handleDice();
}
} }
} }
@@ -47,12 +60,14 @@ namespace Yc {
_users.push_back(newUser); _users.push_back(newUser);
newUser->sendMsg(User::roomList, _parent->jsonRoomList(), "", ""); newUser->sendMsg(User::roomList, _parent->jsonRoomList(), "", "");
addMessage(User::system, "room_entered", newUser->name(), newUser->color()); addMessage(User::system, "room_entered", newUser->name(), newUser->color());
_initRound();
return true; return true;
} }
bool Room::addUser(User *user, std::string password) { bool Room::addUser(User *user, std::string password) {
if (password == _password) { if (password == _password) {
_users.push_back(user); _users.push_back(user);
_initRound();
return true; return true;
} }
return false; return false;
@@ -80,6 +95,10 @@ namespace Yc {
_stop = true; _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) void Room::addMessage(User::MsgType type, std::string messageText, std::string userName, std::string color)
{ {
Message message; Message message;
@@ -90,6 +109,78 @@ namespace Yc {
_msgQueue.push(message); _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<User*, int> val1, std::pair<User*, 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;
entry["value"] = user.second;
userList.append(entry);
}
addMessage(User::result, userList);
}
std::string Room::name() { std::string Room::name() {
return _name; return _name;
} }

36
room.h
View File

@@ -6,16 +6,26 @@
#include <user.h> #include <user.h>
#include <queue> #include <queue>
#include <thread> #include <thread>
#include <future>
#include <utility>
#include <vector>
#include <base.h>
namespace Yc { namespace Yc {
namespace Lib { namespace Lib {
class Server; class Server;
class Room class Room: public Base {
{
public: public:
Room(Server *parent, std::string name, std::string password = "", std::vector<std::string> allowedUsers = std::vector<std::string>()); enum RoomType {
none = 0,
dice = 1,
poker = 2,
rounds = 4
};
Room(Server *parent, Json::Value roomParams);
~Room(); ~Room();
void run(); void run();
std::string name(); std::string name();
@@ -24,7 +34,14 @@ namespace Yc {
bool userNameExists(std::string userName); bool userNameExists(std::string userName);
void removeUser(std::string _token); void removeUser(std::string _token);
void setStop(); 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: private:
struct Message { struct Message {
User::MsgType type; User::MsgType type;
@@ -37,11 +54,22 @@ namespace Yc {
std::string _name; std::string _name;
std::string _password; std::string _password;
std::vector<std::string> _allowedUsers; std::vector<std::string> _allowedUsers;
RoomType _type;
std::vector<User*> _users; std::vector<User*> _users;
bool _blocked; bool _blocked;
bool _stop; bool _stop;
std::queue<Message> _msgQueue; std::queue<Message> _msgQueue;
std::thread *thread; std::thread *thread;
bool _roundRunning;
time_t _roundStart;
time_t _lastRoundEnd;
int _roundLength;
std::vector<std::pair<User *, int>> _diceValues;
void _handleDice();
void _startDiceRound();
void _endDiceRound();
void _initRound();
void _showDiceRoundResults();
}; };
} // namespace Lib } // namespace Lib

View File

@@ -70,13 +70,18 @@ namespace Yc {
return list; 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) { void Server::createRooms(Json::Value roomList) {
for (auto &room: roomList) { for (auto &room: roomList) {
std::vector<std::string> allowedUsers; Room *newRoom = new Room(this, room);
for (auto &user: room["allowed"]) {
allowedUsers.push_back(user.asString());
}
Room *newRoom = new Room(this, room["name"].asString(), room["password"].asString(), allowedUsers);
_rooms.push_back(newRoom); _rooms.push_back(newRoom);
} }
} }

View File

@@ -17,6 +17,7 @@ namespace Yc {
void run(); void run();
std::vector<std::string> roomList(); std::vector<std::string> roomList();
Json::Value jsonRoomList(); Json::Value jsonRoomList();
bool roomAllowed(std::string roomName, std::string userName, std::string password);
private: private:
int _socket; int _socket;
Yc::Lib::Config *_config; Yc::Lib::Config *_config;

View File

@@ -27,7 +27,7 @@ namespace Yc {
User::~User() { User::~User() {
delete thread; 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 { std::string User::name() const {
@@ -42,6 +42,10 @@ namespace Yc {
return (toValidate == this); 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) { void User::sendMsg(MsgType type, std::string message , std::string userName, std::string color) {
Json::Value sendMessage; Json::Value sendMessage;
sendMessage["type"] = type; sendMessage["type"] = type;
@@ -103,6 +107,25 @@ namespace Yc {
Json::Value jsonTree = getJsonTree(message); Json::Value jsonTree = getJsonTree(message);
if (jsonTree["type"].asString() == "message") { if (jsonTree["type"].asString() == "message") {
_parent->addMessage(User::message, jsonTree["message"].asString(), _name, _color); _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 } // namespace Lib

8
user.h
View File

@@ -19,7 +19,11 @@ namespace Yc {
userListe = 2, userListe = 2,
roomList = 3, roomList = 3,
message = 4, 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); User(Room *parent, std::string name, std::string color, int socket);
@@ -28,6 +32,7 @@ namespace Yc {
bool validateToken(std::string token); bool validateToken(std::string token);
bool isUser(User *toValidate); bool isUser(User *toValidate);
void sendMsg(MsgType type, std::string message, std::string userName, std::string color); 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 sendMsg(MsgType type, Json::Value message, std::string userName, std::string color);
void checkerTask(); void checkerTask();
void stop(); void stop();
@@ -43,6 +48,7 @@ namespace Yc {
void send(std::string out); void send(std::string out);
void send(Json::Value out); void send(Json::Value out);
void handleMessage(std::string message); void handleMessage(std::string message);
void doDice();
}; };
} // namespace Lib } // namespace Lib