diff --git a/cockatrice/src/localserver.cpp b/cockatrice/src/localserver.cpp index 613964fd..88c93404 100644 --- a/cockatrice/src/localserver.cpp +++ b/cockatrice/src/localserver.cpp @@ -6,7 +6,7 @@ LocalServer::LocalServer(QObject *parent) : Server(false, parent) { setDatabaseInterface(new LocalServer_DatabaseInterface(this)); - addRoom(new Server_Room(0, QString(), QString(), false, QString(), QStringList(), this)); + addRoom(new Server_Room(0, QString(), QString(), QString(), false, QString(), QStringList(), this)); } LocalServer::~LocalServer() diff --git a/cockatrice/src/tab_server.cpp b/cockatrice/src/tab_server.cpp index 2da72776..927e522d 100644 --- a/cockatrice/src/tab_server.cpp +++ b/cockatrice/src/tab_server.cpp @@ -25,7 +25,7 @@ RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) { roomList = new QTreeWidget; roomList->setRootIsDecorated(false); - roomList->setColumnCount(4); + roomList->setColumnCount(5); roomList->header()->setStretchLastSection(false); #if QT_VERSION < 0x050000 roomList->header()->setResizeMode(0, QHeaderView::ResizeToContents); @@ -35,6 +35,7 @@ RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) #else roomList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); roomList->header()->setSectionResizeMode(1, QHeaderView::Stretch); + roomList->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); roomList->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); roomList->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); #endif @@ -63,10 +64,12 @@ void RoomSelector::retranslateUi() QTreeWidgetItem *header = roomList->headerItem(); header->setText(0, tr("Room")); header->setText(1, tr("Description")); - header->setText(2, tr("Players")); - header->setText(3, tr("Games")); + header->setText(2, tr("Permissions")); + header->setText(3, tr("Players")); + header->setText(4, tr("Games")); header->setTextAlignment(2, Qt::AlignRight); header->setTextAlignment(3, Qt::AlignRight); + header->setTextAlignment(4, Qt::AlignRight); } void RoomSelector::processListRoomsEvent(const Event_ListRooms &event) @@ -82,10 +85,12 @@ void RoomSelector::processListRoomsEvent(const Event_ListRooms &event) twi->setData(0, Qt::DisplayRole, QString::fromStdString(room.name())); if (room.has_description()) twi->setData(1, Qt::DisplayRole, QString::fromStdString(room.description())); + if (room.has_permissionlevel()) + twi->setData(2, Qt::DisplayRole, QString::fromStdString(room.permissionlevel()).toLower()); if (room.has_player_count()) - twi->setData(2, Qt::DisplayRole, room.player_count()); + twi->setData(3, Qt::DisplayRole, room.player_count()); if (room.has_game_count()) - twi->setData(3, Qt::DisplayRole, room.game_count()); + twi->setData(4, Qt::DisplayRole, room.game_count()); return; } } @@ -95,10 +100,13 @@ void RoomSelector::processListRoomsEvent(const Event_ListRooms &event) twi->setData(0, Qt::DisplayRole, QString::fromStdString(room.name())); if (room.has_description()) twi->setData(1, Qt::DisplayRole, QString::fromStdString(room.description())); - twi->setData(2, Qt::DisplayRole, room.player_count()); - twi->setData(3, Qt::DisplayRole, room.game_count()); + if (room.has_permissionlevel()) + twi->setData(2, Qt::DisplayRole, QString::fromStdString(room.permissionlevel()).toLower()); + twi->setData(3, Qt::DisplayRole, room.player_count()); + twi->setData(4, Qt::DisplayRole, room.game_count()); twi->setTextAlignment(2, Qt::AlignRight); twi->setTextAlignment(3, Qt::AlignRight); + twi->setTextAlignment(4, Qt::AlignRight); roomList->addTopLevelItem(twi); if (room.has_auto_join()) @@ -130,10 +138,16 @@ void RoomSelector::joinClicked() void RoomSelector::joinFinished(const Response &r, const CommandContainer & /*commandContainer*/, const QVariant &extraData) { - if (r.response_code() != Response::RespOk) - return; + if (r.response_code() != Response::RespOk) { + switch (r.response_code()) { + case Response::RespUserLevelTooLow: QMessageBox::critical(this, tr("Error"), tr("You do not have the proper permission to join this room.")); return; + default: + QMessageBox::critical(this, tr("Error"), tr("Failed to join the room due to an unknown error.")); + return; + } + } + const Response_JoinRoom &resp = r.GetExtension(Response_JoinRoom::ext); - emit roomJoined(resp.room_info(), extraData.toBool()); } diff --git a/common/pb/serverinfo_room.proto b/common/pb/serverinfo_room.proto index 6455ad89..e7a6b6ab 100644 --- a/common/pb/serverinfo_room.proto +++ b/common/pb/serverinfo_room.proto @@ -12,4 +12,5 @@ message ServerInfo_Room { repeated ServerInfo_Game game_list = 7; repeated ServerInfo_User user_list = 8; repeated ServerInfo_GameType gametype_list = 9; + optional string permissionlevel = 10; } diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 272b8177..291c2ee2 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -542,6 +542,24 @@ Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoo if (!r) return Response::RespNameNotFound; + QString roomPermission = r->getRoomPermission().toLower(); + if (roomPermission != "none"){ + if (roomPermission == "registered") { + if (!(userInfo->user_level() & ServerInfo_User::IsRegistered)) + return Response::RespUserLevelTooLow; + } + + if (roomPermission == "moderator"){ + if (!(userInfo->user_level() & ServerInfo_User::IsModerator)) + return Response::RespUserLevelTooLow; + } + + if (roomPermission == "administrator"){ + if (!(userInfo->user_level() & ServerInfo_User::IsAdmin)) + return Response::RespUserLevelTooLow; + } + } + r->addClient(this); rooms.insert(r->getId(), r); diff --git a/common/server_room.cpp b/common/server_room.cpp index 985fb543..6ce86c8e 100644 --- a/common/server_room.cpp +++ b/common/server_room.cpp @@ -12,8 +12,8 @@ #include "pb/serverinfo_room.pb.h" #include -Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent) - : QObject(parent), id(_id), name(_name), description(_description), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), gamesLock(QReadWriteLock::Recursive) +Server_Room::Server_Room(int _id, const QString &_name, const QString &_description, const QString &_permissionLevel, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent) + : QObject(parent), id(_id), name(_name), description(_description), permissionLevel(_permissionLevel), autoJoin(_autoJoin), joinMessage(_joinMessage), gameTypes(_gameTypes), gamesLock(QReadWriteLock::Recursive) { connect(this, SIGNAL(gameListChanged(ServerInfo_Game)), this, SLOT(broadcastGameListUpdate(ServerInfo_Game)), Qt::QueuedConnection); } @@ -46,6 +46,7 @@ const ServerInfo_Room &Server_Room::getInfo(ServerInfo_Room &result, bool comple result.set_name(name.toStdString()); result.set_description(description.toStdString()); result.set_auto_join(autoJoin); + result.set_permissionlevel(permissionLevel.toStdString()); gamesLock.lockForRead(); result.set_game_count(games.size() + externalGames.size()); diff --git a/common/server_room.h b/common/server_room.h index bf91510c..3bb0e05e 100644 --- a/common/server_room.h +++ b/common/server_room.h @@ -32,6 +32,7 @@ private: int id; QString name; QString description; + QString permissionLevel; bool autoJoin; QString joinMessage; QStringList gameTypes; @@ -44,11 +45,12 @@ private slots: public: mutable QReadWriteLock usersLock; mutable QReadWriteLock gamesLock; - Server_Room(int _id, const QString &_name, const QString &_description, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); + Server_Room(int _id, const QString &_name, const QString &_description, const QString &_permissionLevel, bool _autoJoin, const QString &_joinMessage, const QStringList &_gameTypes, Server *parent); ~Server_Room(); int getId() const { return id; } QString getName() const { return name; } QString getDescription() const { return description; } + QString getRoomPermission() const { return permissionLevel; } bool getAutoJoin() const { return autoJoin; } QString getJoinMessage() const { return joinMessage; } const QStringList &getGameTypes() const { return gameTypes; } diff --git a/servatrice/migrations/servatrice_0006_to_0007.sql b/servatrice/migrations/servatrice_0006_to_0007.sql new file mode 100644 index 00000000..651105a8 --- /dev/null +++ b/servatrice/migrations/servatrice_0006_to_0007.sql @@ -0,0 +1,5 @@ +-- Servatrice db migration from version 6 to version 7 + +alter table cockatrice_rooms add permissionlevel varchar(20) not null after descr; + +UPDATE cockatrice_schema_version SET version=7 WHERE version=6; diff --git a/servatrice/servatrice.ini.example b/servatrice/servatrice.ini.example index f8aeffa7..ce57df53 100644 --- a/servatrice/servatrice.ini.example +++ b/servatrice/servatrice.ini.example @@ -172,6 +172,10 @@ roomlist\1\name="General room" ; Room description for the room number 1 roomlist\1\description="Play anything here." +; Rooms can restrict the level of user that can join. Current supported options are none, registered, moderator, administrator. +; Default is none. +roomlist\1\permissionlevel=none + ; Wether to make users autojoin this room when connected to the server roomlist\1\autojoin=true diff --git a/servatrice/servatrice.sql b/servatrice/servatrice.sql index 27280167..e2ea0f9d 100644 --- a/servatrice/servatrice.sql +++ b/servatrice/servatrice.sql @@ -183,6 +183,7 @@ CREATE TABLE IF NOT EXISTS `cockatrice_rooms` ( `id` int(7) unsigned NOT NULL auto_increment, `name` varchar(50) NOT NULL, `descr` varchar(255) NOT NULL, + `permissionlevel` varchar(20) NOT NULL, `auto_join` tinyint(1) default 0, `join_message` varchar(255) NOT NULL, PRIMARY KEY (`id`) diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 0f56003c..701902f8 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -211,7 +211,7 @@ bool Servatrice::initServer() const QString roomMethod = settingsCache->value("rooms/method").toString(); if (roomMethod == "sql") { - QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, name, descr, auto_join, join_message from {prefix}_rooms order by id asc"); + QSqlQuery *query = servatriceDatabaseInterface->prepareQuery("select id, name, descr, permissionlevel, auto_join, join_message from {prefix}_rooms order by id asc"); servatriceDatabaseInterface->execSqlQuery(query); while (query->next()) { QSqlQuery *query2 = servatriceDatabaseInterface->prepareQuery("select name from {prefix}_rooms_gametypes where id_room = :id_room"); @@ -224,8 +224,9 @@ bool Servatrice::initServer() addRoom(new Server_Room(query->value(0).toInt(), query->value(1).toString(), query->value(2).toString(), - query->value(3).toInt(), - query->value(4).toString(), + query->value(3).toString().toLower(), + query->value(4).toInt(), + query->value(5).toString(), gameTypes, this )); @@ -247,6 +248,7 @@ bool Servatrice::initServer() i, settingsCache->value("name").toString(), settingsCache->value("description").toString(), + settingsCache->value("permissionlevel").toString().toLower(), settingsCache->value("autojoin").toBool(), settingsCache->value("joinmessage").toString(), gameTypes, @@ -262,6 +264,7 @@ bool Servatrice::initServer() 0, "General room", "Play anything here.", + "none", true, "", QStringList("Standard"), diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index d082b2f3..0ca48440 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -9,7 +9,7 @@ #include "server.h" #include "server_database_interface.h" -#define DATABASE_SCHEMA_VERSION 6 +#define DATABASE_SCHEMA_VERSION 7 class Servatrice;