diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index b1239c4ad..27709eb72 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -159,6 +159,7 @@ set(cockatrice_SOURCES src/server/user/user_context_menu.cpp src/server/user/user_info_connection.cpp src/server/user/user_info_box.cpp + src/server/user/user_list_manager.cpp src/server/user/user_list_widget.cpp src/client/ui/window_main.cpp src/game/zones/view_zone_widget.cpp diff --git a/cockatrice/src/client/tabs/tab_account.h b/cockatrice/src/client/tabs/tab_account.h index 203dcd6c3..14a1cd189 100644 --- a/cockatrice/src/client/tabs/tab_account.h +++ b/cockatrice/src/client/tabs/tab_account.h @@ -52,18 +52,6 @@ public: { return tr("Account"); } - const UserListWidget *getAllUsersList() const - { - return allUsersList; - } - const UserListWidget *getBuddyList() const - { - return buddyList; - } - const UserListWidget *getIgnoreList() const - { - return ignoreList; - } }; #endif diff --git a/cockatrice/src/client/tabs/tab_game.cpp b/cockatrice/src/client/tabs/tab_game.cpp index 919880603..a816c8fbb 100644 --- a/cockatrice/src/client/tabs/tab_game.cpp +++ b/cockatrice/src/client/tabs/tab_game.cpp @@ -123,15 +123,16 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay) } TabGame::TabGame(TabSupervisor *_tabSupervisor, + UserlistProxy *_userListProxy, QList &_clients, const Event_GameJoined &event, const QMap &_roomGameTypes) - : Tab(_tabSupervisor), clients(_clients), gameInfo(event.game_info()), roomGameTypes(_roomGameTypes), - hostId(event.host_id()), localPlayerId(event.player_id()), isLocalGame(_tabSupervisor->getIsLocalGame()), - spectator(event.spectator()), judge(event.judge()), gameStateKnown(false), resuming(event.resuming()), - currentPhase(-1), activeCard(nullptr), gameClosed(false), replay(nullptr), replayPlayButton(nullptr), - replayFastForwardButton(nullptr), aReplaySkipForward(nullptr), aReplaySkipBackward(nullptr), - aReplaySkipForwardBig(nullptr), aReplaySkipBackwardBig(nullptr), replayDock(nullptr) + : Tab(_tabSupervisor), userListProxy(_userListProxy), clients(_clients), gameInfo(event.game_info()), + roomGameTypes(_roomGameTypes), hostId(event.host_id()), localPlayerId(event.player_id()), + isLocalGame(_tabSupervisor->getIsLocalGame()), spectator(event.spectator()), judge(event.judge()), + gameStateKnown(false), resuming(event.resuming()), currentPhase(-1), activeCard(nullptr), gameClosed(false), + replay(nullptr), replayPlayButton(nullptr), replayFastForwardButton(nullptr), aReplaySkipForward(nullptr), + aReplaySkipBackward(nullptr), aReplaySkipForwardBig(nullptr), aReplaySkipBackwardBig(nullptr), replayDock(nullptr) { // THIS CTOR IS USED ON GAMES gameInfo.set_started(false); @@ -1683,7 +1684,7 @@ void TabGame::createPlayerListDock(bool bReplay) void TabGame::createMessageDock(bool bReplay) { - messageLog = new MessageLogWidget(tabSupervisor, tabSupervisor, this); + messageLog = new MessageLogWidget(tabSupervisor, userListProxy, this); connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfoFrameWidget, SLOT(setCard(QString))); connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup); connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); diff --git a/cockatrice/src/client/tabs/tab_game.h b/cockatrice/src/client/tabs/tab_game.h index 4e59712c6..26bca83c3 100644 --- a/cockatrice/src/client/tabs/tab_game.h +++ b/cockatrice/src/client/tabs/tab_game.h @@ -11,6 +11,7 @@ #include #include +class UserlistProxy; class DeckViewContainer; class AbstractClient; class CardDatabase; @@ -66,6 +67,7 @@ class TabGame : public Tab private: QTimer *gameTimer; int secondsElapsed; + UserlistProxy *userListProxy; QList clients; ServerInfo_Game gameInfo; QMap roomGameTypes; @@ -210,6 +212,7 @@ private slots: public: TabGame(TabSupervisor *_tabSupervisor, + UserlistProxy *_userListProxy, QList &_clients, const Event_GameJoined &event, const QMap &_roomGameTypes); diff --git a/cockatrice/src/client/tabs/tab_message.cpp b/cockatrice/src/client/tabs/tab_message.cpp index c65ec66fe..63466e7f3 100644 --- a/cockatrice/src/client/tabs/tab_message.cpp +++ b/cockatrice/src/client/tabs/tab_message.cpp @@ -4,6 +4,7 @@ #include "../../main.h" #include "../../server/chat_view/chat_view.h" #include "../../server/pending_command.h" +#include "../../server/user/user_list_manager.h" #include "../../settings/cache_settings.h" #include "../game_logic/abstract_client.h" #include "../sound_engine.h" @@ -25,7 +26,7 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor, : Tab(_tabSupervisor), client(_client), ownUserInfo(new ServerInfo_User(_ownUserInfo)), otherUserInfo(new ServerInfo_User(_otherUserInfo)), userOnline(true) { - chatView = new ChatView(tabSupervisor, tabSupervisor, 0, true); + chatView = new ChatView(tabSupervisor, tabSupervisor->getUserListManager(), 0, true); connect(chatView, &ChatView::showCardInfoPopup, this, &TabMessage::showCardInfoPopup); connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString))); connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString))); diff --git a/cockatrice/src/client/tabs/tab_room.cpp b/cockatrice/src/client/tabs/tab_room.cpp index 4f3b26714..9fd5473f0 100644 --- a/cockatrice/src/client/tabs/tab_room.cpp +++ b/cockatrice/src/client/tabs/tab_room.cpp @@ -6,6 +6,7 @@ #include "../../main.h" #include "../../server/chat_view/chat_view.h" #include "../../server/pending_command.h" +#include "../../server/user/user_list_manager.h" #include "../../server/user/user_list_widget.h" #include "../../settings/cache_settings.h" #include "get_pb_extension.h" @@ -35,9 +36,10 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerInfo_User *_ownUser, + const UserlistProxy *_userListProxy, const ServerInfo_Room &info) : Tab(_tabSupervisor), client(_client), roomId(info.room_id()), roomName(QString::fromStdString(info.name())), - ownUser(_ownUser) + ownUser(_ownUser), userListProxy(_userListProxy) { const int gameTypeListSize = info.gametype_list_size(); for (int i = 0; i < gameTypeListSize; ++i) @@ -51,7 +53,7 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor, connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool))); - chatView = new ChatView(tabSupervisor, tabSupervisor, nullptr, true, this); + chatView = new ChatView(tabSupervisor, userListProxy, nullptr, true, this); connect(chatView, SIGNAL(showMentionPopup(const QString &)), this, SLOT(actShowMentionPopup(const QString &))); connect(chatView, SIGNAL(messageClickedSignal()), this, SLOT(focusTab())); connect(chatView, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool))); @@ -282,7 +284,7 @@ void TabRoom::processRoomSayEvent(const Event_RoomSay &event) QString senderName = QString::fromStdString(event.name()); QString message = QString::fromStdString(event.message()); - if (tabSupervisor->getTabAccount()->getIgnoreList()->getUsers().contains(senderName)) + if (userListProxy->getOnlineUser(senderName)) return; UserListTWI *twi = userList->getUsers().value(senderName); diff --git a/cockatrice/src/client/tabs/tab_room.h b/cockatrice/src/client/tabs/tab_room.h index 6039ecc36..92730c9a0 100644 --- a/cockatrice/src/client/tabs/tab_room.h +++ b/cockatrice/src/client/tabs/tab_room.h @@ -9,6 +9,8 @@ #include #include +class UserlistProxy; +class UserListManager; namespace google { namespace protobuf @@ -49,6 +51,7 @@ private: GameSelector *gameSelector; UserListWidget *userList; + const UserlistProxy *userListProxy; ChatView *chatView; QLabel *sayLabel; LineEditCompleter *sayEdit; @@ -89,6 +92,7 @@ public: TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, ServerInfo_User *_ownUser, + const UserlistProxy *_userListProxy, const ServerInfo_Room &info); void retranslateUi() override; void closeRequest(bool forced = false) override; diff --git a/cockatrice/src/client/tabs/tab_supervisor.cpp b/cockatrice/src/client/tabs/tab_supervisor.cpp index 0e1e41db5..240714d85 100644 --- a/cockatrice/src/client/tabs/tab_supervisor.cpp +++ b/cockatrice/src/client/tabs/tab_supervisor.cpp @@ -2,6 +2,7 @@ #include "../../client/game_logic/abstract_client.h" #include "../../main.h" +#include "../../server/user/user_list_manager.h" #include "../../server/user/user_list_widget.h" #include "../../settings/cache_settings.h" #include "../ui/pixel_map_generator.h" @@ -114,6 +115,8 @@ TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget * tabBar()->setStyle(new MacOSTabFixStyle); #endif + userListManager = new UserListManager(client, this); + // connect tab changes connect(this, &TabSupervisor::currentChanged, this, &TabSupervisor::updateCurrent); @@ -291,6 +294,8 @@ void TabSupervisor::start(const ServerInfo_User &_userInfo) isLocalGame = false; userInfo = new ServerInfo_User(_userInfo); + userListManager->handleConnect(); + resetTabsMenu(); tabsMenu->addSeparator(); @@ -395,6 +400,8 @@ void TabSupervisor::stop() tab->closeRequest(true); } + userListManager->handleDisconnect(); + delete userInfo; userInfo = 0; } @@ -535,7 +542,7 @@ void TabSupervisor::gameJoined(const Event_GameJoined &event) roomGameTypes.insert(event.game_types(i).game_type_id(), QString::fromStdString(event.game_types(i).description())); - TabGame *tab = new TabGame(this, QList() << client, event, roomGameTypes); + TabGame *tab = new TabGame(this, userListManager, QList() << client, event, roomGameTypes); connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft); connect(tab, &TabGame::openMessageDialog, this, &TabSupervisor::addMessageTab); connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab); @@ -546,7 +553,7 @@ void TabSupervisor::gameJoined(const Event_GameJoined &event) void TabSupervisor::localGameJoined(const Event_GameJoined &event) { - TabGame *tab = new TabGame(this, localClients, event, QMap()); + TabGame *tab = new TabGame(this, userListManager, localClients, event, QMap()); connect(tab, &TabGame::gameClosing, this, &TabSupervisor::gameLeft); connect(tab, &TabGame::openDeckEditor, this, &TabSupervisor::addDeckEditorTab); myAddTab(tab); @@ -574,7 +581,7 @@ void TabSupervisor::gameLeft(TabGame *tab) void TabSupervisor::addRoomTab(const ServerInfo_Room &info, bool setCurrent) { - TabRoom *tab = new TabRoom(this, client, userInfo, info); + TabRoom *tab = new TabRoom(this, client, userInfo, userListManager, info); connect(tab, &TabRoom::maximizeClient, this, &TabSupervisor::maximizeMainWindow); connect(tab, &TabRoom::roomClosing, this, &TabSupervisor::roomLeft); connect(tab, &TabRoom::openMessageDialog, this, &TabSupervisor::addMessageTab); @@ -616,11 +623,11 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus return nullptr; ServerInfo_User otherUser; - UserListTWI *twi = tabAccount->getAllUsersList()->getUsers().value(receiverName); - if (twi) - otherUser = twi->getUserInfo(); - else + if (auto user = userListManager->getOnlineUser(receiverName)) { + otherUser = ServerInfo_User(*user); + } else { otherUser.set_name(receiverName.toStdString()); + } TabMessage *tab; tab = messageTabs.value(QString::fromStdString(otherUser.name())); @@ -717,9 +724,9 @@ void TabSupervisor::processUserMessageEvent(const Event_UserMessage &event) if (!tab) tab = messageTabs.value(QString::fromStdString(event.receiver_name())); if (!tab) { - UserListTWI *twi = tabAccount->getAllUsersList()->getUsers().value(senderName); - if (twi) { - UserLevelFlags userLevel = UserLevelFlags(twi->getUserInfo().user_level()); + const ServerInfo_User *userInfo = userListManager->getOnlineUser(senderName); + if (userInfo) { + UserLevelFlags userLevel = UserLevelFlags(userInfo->user_level()); if (SettingsCache::instance().getIgnoreUnregisteredUserMessages() && !userLevel.testFlag(ServerInfo_User::IsRegistered)) // Flags are additive, so reg/mod/admin are all IsRegistered @@ -753,15 +760,15 @@ void TabSupervisor::processUserLeft(const QString &userName) void TabSupervisor::processUserJoined(const ServerInfo_User &userInfoJoined) { QString userName = QString::fromStdString(userInfoJoined.name()); - if (isUserBuddy(userName)) { - Tab *tab = static_cast(getTabAccount()); - - if (tab != currentWidget()) { - tab->setContentsChanged(true); - QPixmap avatarPixmap = - UserLevelPixmapGenerator::generatePixmap(13, (UserLevelFlags)userInfoJoined.user_level(), true, - QString::fromStdString(userInfoJoined.privlevel())); - setTabIcon(indexOf(tab), QPixmap(avatarPixmap)); + if (userListManager->isUserBuddy(userName)) { + if (auto *tab = getTabAccount()) { + if (tab != currentWidget()) { + tab->setContentsChanged(true); + QPixmap avatarPixmap = + UserLevelPixmapGenerator::generatePixmap(13, (UserLevelFlags)userInfoJoined.user_level(), true, + QString::fromStdString(userInfoJoined.privlevel())); + setTabIcon(indexOf(tab), QPixmap(avatarPixmap)); + } } if (SettingsCache::instance().getBuddyConnectNotificationsEnabled()) { @@ -849,57 +856,6 @@ void TabSupervisor::processNotifyUserEvent(const Event_NotifyUser &event) } } -bool TabSupervisor::isOwnUserRegistered() const -{ - return userInfo != nullptr && (userInfo->user_level() & ServerInfo_User::IsRegistered) != 0; -} - -QString TabSupervisor::getOwnUsername() const -{ - return userInfo != nullptr ? QString::fromStdString(userInfo->name()) : QString(); -} - -bool TabSupervisor::isUserBuddy(const QString &userName) const -{ - if (!getTabAccount()) - return false; - if (!getTabAccount()->getBuddyList()) - return false; - QMap buddyList = getTabAccount()->getBuddyList()->getUsers(); - bool senderIsBuddy = buddyList.contains(userName); - return senderIsBuddy; -} - -bool TabSupervisor::isUserIgnored(const QString &userName) const -{ - if (!getTabAccount()) - return false; - if (!getTabAccount()->getIgnoreList()) - return false; - QMap buddyList = getTabAccount()->getIgnoreList()->getUsers(); - bool senderIsBuddy = buddyList.contains(userName); - return senderIsBuddy; -} - -const ServerInfo_User *TabSupervisor::getOnlineUser(const QString &userName) const -{ - if (!getTabAccount()) - return nullptr; - if (!getTabAccount()->getAllUsersList()) - return nullptr; - QMap userList = getTabAccount()->getAllUsersList()->getUsers(); - const QString &userNameToMatchLower = userName.toLower(); - QMap::iterator i; - - for (i = userList.begin(); i != userList.end(); ++i) - if (i.key().toLower() == userNameToMatchLower) { - const ServerInfo_User &_userInfo = i.value()->getUserInfo(); - return &_userInfo; - } - - return nullptr; -}; - bool TabSupervisor::switchToGameTabIfAlreadyExists(const int gameId) { bool isGameTabExists = false; diff --git a/cockatrice/src/client/tabs/tab_supervisor.h b/cockatrice/src/client/tabs/tab_supervisor.h index d193b285c..ff09a3bb1 100644 --- a/cockatrice/src/client/tabs/tab_supervisor.h +++ b/cockatrice/src/client/tabs/tab_supervisor.h @@ -11,6 +11,7 @@ #include #include +class UserListManager; class QMenu; class AbstractClient; class Tab; @@ -62,12 +63,13 @@ protected: void paintEvent(QPaintEvent *event) override; }; -class TabSupervisor : public QTabWidget, public UserlistProxy +class TabSupervisor : public QTabWidget { Q_OBJECT private: ServerInfo_User *userInfo; AbstractClient *client; + UserListManager *userListManager; QList localClients; QMenu *tabsMenu; TabDeckStorageVisual *tabVisualDeckStorage; @@ -117,17 +119,16 @@ public: return userInfo; } AbstractClient *getClient() const; + const UserListManager *getUserListManager() const + { + return userListManager; + } const QMap &getRoomTabs() const { return roomTabs; } bool getAdminLocked() const; bool closeRequest(); - bool isOwnUserRegistered() const override; - QString getOwnUsername() const override; - bool isUserBuddy(const QString &userName) const override; - bool isUserIgnored(const QString &userName) const override; - const ServerInfo_User *getOnlineUser(const QString &userName) const override; bool switchToGameTabIfAlreadyExists(const int gameId); void actShowPopup(const QString &message); signals: diff --git a/cockatrice/src/game/game_selector.cpp b/cockatrice/src/game/game_selector.cpp index 3a785d4e2..ab996e038 100644 --- a/cockatrice/src/game/game_selector.cpp +++ b/cockatrice/src/game/game_selector.cpp @@ -9,6 +9,7 @@ #include "../dialogs/dlg_create_game.h" #include "../dialogs/dlg_filter_games.h" #include "../server/pending_command.h" +#include "../server/user/user_list_manager.h" #include "games_model.h" #include "pb/response.pb.h" #include "pb/room_commands.pb.h" @@ -39,7 +40,7 @@ GameSelector::GameSelector(AbstractClient *_client, gameListView = new QTreeView; gameListModel = new GamesModel(_rooms, _gameTypes, this); if (showFilters) { - gameListProxyModel = new GamesProxyModel(this, tabSupervisor); + gameListProxyModel = new GamesProxyModel(this, tabSupervisor->getUserListManager()); gameListProxyModel->setSourceModel(gameListModel); gameListProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); gameListView->setModel(gameListProxyModel); diff --git a/cockatrice/src/game/games_model.cpp b/cockatrice/src/game/games_model.cpp index a2b42ee7a..c7151d25b 100644 --- a/cockatrice/src/game/games_model.cpp +++ b/cockatrice/src/game/games_model.cpp @@ -2,6 +2,7 @@ #include "../client/tabs/tab_account.h" #include "../client/ui/pixel_map_generator.h" +#include "../server/user/user_list_manager.h" #include "../server/user/user_list_widget.h" #include "../settings/cache_settings.h" #include "pb/serverinfo_game.pb.h" @@ -284,9 +285,8 @@ void GamesModel::updateGameList(const ServerInfo_Game &game) endInsertRows(); } -GamesProxyModel::GamesProxyModel(QObject *parent, const TabSupervisor *_tabSupervisor) - : QSortFilterProxyModel(parent), ownUserIsRegistered(_tabSupervisor->isOwnUserRegistered()), - tabSupervisor(_tabSupervisor) +GamesProxyModel::GamesProxyModel(QObject *parent, const UserlistProxy *_userListProxy) + : QSortFilterProxyModel(parent), userListProxy(_userListProxy) { resetFilterParameters(); setSortRole(GamesModel::SORT_ROLE); @@ -508,15 +508,14 @@ bool GamesProxyModel::filterAcceptsRow(int sourceRow) const if (!showBuddiesOnlyGames && game.only_buddies()) { return false; } - if (hideIgnoredUserGames && tabSupervisor->getTabAccount()->getIgnoreList()->getUsers().contains( - QString::fromStdString(game.creator_info().name()))) { + if (hideIgnoredUserGames && userListProxy->isUserIgnored(QString::fromStdString(game.creator_info().name()))) { return false; } if (!showFullGames && game.player_count() == game.max_players()) return false; if (!showGamesThatStarted && game.started()) return false; - if (!ownUserIsRegistered) + if (!userListProxy->isOwnUserRegistered()) if (game.only_registered()) return false; if (!showPasswordProtectedGames && game.with_password()) diff --git a/cockatrice/src/game/games_model.h b/cockatrice/src/game/games_model.h index 655608d26..68b76a1ad 100644 --- a/cockatrice/src/game/games_model.h +++ b/cockatrice/src/game/games_model.h @@ -1,7 +1,6 @@ #ifndef GAMESMODEL_H #define GAMESMODEL_H -#include "../client/tabs/tab_supervisor.h" #include "game_type_map.h" #include "pb/serverinfo_game.pb.h" @@ -12,6 +11,8 @@ #include #include +class UserlistProxy; + class GamesModel : public QAbstractTableModel { Q_OBJECT @@ -65,8 +66,7 @@ class GamesProxyModel : public QSortFilterProxyModel { Q_OBJECT private: - bool ownUserIsRegistered; - const TabSupervisor *tabSupervisor; + const UserlistProxy *userListProxy; // If adding any additional filters, make sure to update: // - GamesProxyModel() @@ -88,7 +88,7 @@ private: showOnlyIfSpectatorsCanSeeHands; public: - GamesProxyModel(QObject *parent = nullptr, const TabSupervisor *_tabSupervisor = nullptr); + GamesProxyModel(QObject *parent = nullptr, const UserlistProxy *_userListProxy = nullptr); bool getShowBuddiesOnlyGames() const { diff --git a/cockatrice/src/game/player/player_list_widget.cpp b/cockatrice/src/game/player/player_list_widget.cpp index bca98a35b..acb1186f6 100644 --- a/cockatrice/src/game/player/player_list_widget.cpp +++ b/cockatrice/src/game/player/player_list_widget.cpp @@ -6,6 +6,7 @@ #include "../../client/tabs/tab_supervisor.h" #include "../../client/ui/pixel_map_generator.h" #include "../../server/user/user_context_menu.h" +#include "../../server/user/user_list_manager.h" #include "../../server/user/user_list_widget.h" #include "pb/command_kick_from_game.pb.h" #include "pb/serverinfo_playerproperties.pb.h" @@ -71,7 +72,7 @@ PlayerListWidget::PlayerListWidget(TabSupervisor *_tabSupervisor, itemDelegate = new PlayerListItemDelegate(this); setItemDelegate(itemDelegate); - userContextMenu = new UserContextMenu(tabSupervisor, this, game); + userContextMenu = new UserContextMenu(tabSupervisor, tabSupervisor->getUserListManager(), this, game); connect(userContextMenu, &UserContextMenu::openMessageDialog, this, &PlayerListWidget::openMessageDialog); } else { userContextMenu = nullptr; diff --git a/cockatrice/src/server/chat_view/chat_view.cpp b/cockatrice/src/server/chat_view/chat_view.cpp index 1a0e21b82..a78ccce10 100644 --- a/cockatrice/src/server/chat_view/chat_view.cpp +++ b/cockatrice/src/server/chat_view/chat_view.cpp @@ -45,7 +45,7 @@ ChatView::ChatView(TabSupervisor *_tabSupervisor, linkColor = palette().link().color(); } - userContextMenu = new UserContextMenu(tabSupervisor, this, game); + userContextMenu = new UserContextMenu(tabSupervisor, userlistProxy, this, game); connect(userContextMenu, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool))); ownUserName = userlistProxy->getOwnUsername(); diff --git a/cockatrice/src/server/user/user_context_menu.cpp b/cockatrice/src/server/user/user_context_menu.cpp index 8b055af34..4afeb9ed1 100644 --- a/cockatrice/src/server/user/user_context_menu.cpp +++ b/cockatrice/src/server/user/user_context_menu.cpp @@ -5,6 +5,7 @@ #include "../../client/tabs/tab_game.h" #include "../../client/tabs/tab_supervisor.h" #include "../../game/game_selector.h" +#include "../../server/chat_view/user_list_proxy.h" #include "../chat_view/chat_view.h" #include "../pending_command.h" #include "pb/command_kick_from_game.pb.h" @@ -27,8 +28,12 @@ #include #include -UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *parent, TabGame *_game) - : QObject(parent), client(_tabSupervisor->getClient()), tabSupervisor(_tabSupervisor), game(_game) +UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, + const UserlistProxy *_userListProxy, + QWidget *parent, + TabGame *_game) + : QObject(parent), client(_tabSupervisor->getClient()), tabSupervisor(_tabSupervisor), + userListProxy(_userListProxy), game(_game) { aUserName = new QAction(QString(), this); aUserName->setEnabled(false); @@ -284,7 +289,7 @@ void UserContextMenu::warnUser_dialogFinished() { WarningDialog *dlg = static_cast(sender()); - if (dlg->getName().isEmpty() || tabSupervisor->getOwnUsername().simplified().isEmpty()) + if (dlg->getName().isEmpty() || userListProxy->getOwnUsername().simplified().isEmpty()) return; Command_WarnUser cmd; @@ -348,14 +353,14 @@ void UserContextMenu::showContextMenu(const QPoint &pos, menu->addAction(aDetails); menu->addAction(aShowGames); menu->addAction(aChat); - if (userLevel.testFlag(ServerInfo_User::IsRegistered) && tabSupervisor->isOwnUserRegistered()) { + if (userLevel.testFlag(ServerInfo_User::IsRegistered) && userListProxy->isOwnUserRegistered()) { menu->addSeparator(); - if (tabSupervisor->isUserBuddy(userName)) { + if (userListProxy->isUserBuddy(userName)) { menu->addAction(aRemoveFromBuddyList); } else { menu->addAction(aAddToBuddyList); } - if (tabSupervisor->isUserIgnored(userName)) { + if (userListProxy->isUserIgnored(userName)) { menu->addAction(aRemoveFromIgnoreList); } else { menu->addAction(aAddToIgnoreList); @@ -398,7 +403,7 @@ void UserContextMenu::showContextMenu(const QPoint &pos, menu->addAction(aPromoteToJudge); } } - bool anotherUser = userName != tabSupervisor->getOwnUsername(); + bool anotherUser = userName != userListProxy->getOwnUsername(); aDetails->setEnabled(true); aChat->setEnabled(anotherUser && online); aShowGames->setEnabled(online); diff --git a/cockatrice/src/server/user/user_context_menu.h b/cockatrice/src/server/user/user_context_menu.h index ddbf47b45..5282b26e6 100644 --- a/cockatrice/src/server/user/user_context_menu.h +++ b/cockatrice/src/server/user/user_context_menu.h @@ -5,6 +5,7 @@ #include +class UserlistProxy; class AbstractClient; class ChatView; class CommandContainer; @@ -22,6 +23,7 @@ class UserContextMenu : public QObject private: AbstractClient *client; TabSupervisor *tabSupervisor; + const UserlistProxy *userListProxy; TabGame *game; QAction *aUserName; @@ -52,7 +54,10 @@ private slots: void gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer); public: - UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *_parent, TabGame *_game = 0); + UserContextMenu(TabSupervisor *_tabSupervisor, + const UserlistProxy *_userListProxy, + QWidget *_parent, + TabGame *_game = 0); void retranslateUi(); void showContextMenu(const QPoint &pos, const QString &userName, diff --git a/cockatrice/src/server/user/user_list_manager.cpp b/cockatrice/src/server/user/user_list_manager.cpp new file mode 100644 index 000000000..b1443b02e --- /dev/null +++ b/cockatrice/src/server/user/user_list_manager.cpp @@ -0,0 +1,170 @@ +#include "user_list_manager.h" + +#include "../../client/game_logic/abstract_client.h" +#include "../../client/sound_engine.h" +#include "../pending_command.h" +#include "pb/event_add_to_list.pb.h" +#include "pb/event_remove_from_list.pb.h" +#include "pb/event_user_joined.pb.h" +#include "pb/event_user_left.pb.h" +#include "pb/response_list_users.pb.h" +#include "pb/session_commands.pb.h" +#include "user_info_box.h" + +UserListManager::UserListManager(AbstractClient *_client, QWidget *parent) + : QWidget(parent), client(_client), ownUserInfo(nullptr) +{ + connect(client, &AbstractClient::userJoinedEventReceived, this, &UserListManager::processUserJoinedEvent); + connect(client, &AbstractClient::userLeftEventReceived, this, &UserListManager::processUserLeftEvent); + connect(client, &AbstractClient::buddyListReceived, this, &UserListManager::buddyListReceived); + connect(client, &AbstractClient::ignoreListReceived, this, &UserListManager::ignoreListReceived); + connect(client, &AbstractClient::addToListEventReceived, this, &UserListManager::processAddToListEvent); + connect(client, &AbstractClient::removeFromListEventReceived, this, &UserListManager::processRemoveFromListEvent); + connect(client, &AbstractClient::userInfoChanged, this, &UserListManager::setOwnUserInfo); +} + +UserListManager::~UserListManager() +{ + handleDisconnect(); +} + +void UserListManager::handleConnect() +{ + populateInitialOnlineUsers(); +} + +void UserListManager::handleDisconnect() +{ + onlineUsers.clear(); + buddyUsers.clear(); + ignoredUsers.clear(); + + delete ownUserInfo; + ownUserInfo = nullptr; +} + +void UserListManager::setOwnUserInfo(const ServerInfo_User &userInfo) +{ + ownUserInfo = new ServerInfo_User(userInfo); +} + +void UserListManager::populateInitialOnlineUsers() +{ + PendingCommand *pend = client->prepareSessionCommand(Command_ListUsers()); + connect(pend, qOverload(&PendingCommand::finished), + this, &UserListManager::processListUsersResponse); + client->sendCommand(pend); +} + +void UserListManager::processListUsersResponse(const Response &response) +{ + const auto &resp = response.GetExtension(Response_ListUsers::ext); + + const int userListSize = resp.user_list_size(); + for (int i = 0; i < userListSize; ++i) { + const ServerInfo_User &info = resp.user_list(i); + const QString &userName = QString::fromStdString(info.name()); + onlineUsers.insert(userName, info); + } +} + +void UserListManager::processUserJoinedEvent(const Event_UserJoined &event) +{ + const auto &info = event.user_info(); + const QString &userName = QString::fromStdString(info.name()); + onlineUsers.insert(userName, info); +} + +void UserListManager::processUserLeftEvent(const Event_UserLeft &event) +{ + const auto &userName = QString::fromStdString(event.name()); + onlineUsers.remove(userName); +} + +void UserListManager::buddyListReceived(const QList &_buddyList) +{ + for (const auto &user : _buddyList) { + const auto &userName = QString::fromStdString(user.name()); + buddyUsers.insert(userName, user); + } +} + +void UserListManager::ignoreListReceived(const QList &_ignoreList) +{ + for (const auto &user : _ignoreList) { + const auto &userName = QString::fromStdString(user.name()); + ignoredUsers.insert(userName, user); + } +} + +void UserListManager::processAddToListEvent(const Event_AddToList &event) +{ + const auto &user = event.user_info(); + const auto &userName = QString::fromStdString(user.name()); + + const auto &userListType = QString::fromStdString(event.list_name()); + + QMap userMap; + if (userListType == "buddy") { + userMap = buddyUsers; + } else if (userListType == "ignore") { + userMap = ignoredUsers; + } else { + return; + } + + userMap.insert(userName, user); +} + +void UserListManager::processRemoveFromListEvent(const Event_RemoveFromList &event) +{ + const auto &userListType = QString::fromStdString(event.list_name()); + const auto &userName = QString::fromStdString(event.user_name()); + + QMap userMap; + if (userListType == "buddy") { + userMap = buddyUsers; + } else if (userListType == "ignore") { + userMap = ignoredUsers; + } else { + return; + } + + userMap.remove(userName); +} + +bool UserListManager::isOwnUserRegistered() const +{ + return ownUserInfo != nullptr && (ownUserInfo->user_level() & ServerInfo_User::IsRegistered) != 0; +} + +QString UserListManager::getOwnUsername() const +{ + return ownUserInfo != nullptr ? QString::fromStdString(ownUserInfo->name()) : QString(); +} + +bool UserListManager::isUserBuddy(const QString &userName) const +{ + return buddyUsers.contains(userName); +} + +bool UserListManager::isUserIgnored(const QString &userName) const +{ + return ignoredUsers.contains(userName); +} + +const ServerInfo_User *UserListManager::getOnlineUser(const QString &userName) const +{ + const QString &userNameToMatchLower = userName.toLower(); + + const auto it = + std::find_if(onlineUsers.begin(), onlineUsers.end(), [&userNameToMatchLower](const ServerInfo_User &user) { + return userNameToMatchLower == QString::fromStdString(user.name()).toLower(); + }); + + if (it != onlineUsers.end()) { + return &*it; + } + + return nullptr; +}; \ No newline at end of file diff --git a/cockatrice/src/server/user/user_list_manager.h b/cockatrice/src/server/user/user_list_manager.h new file mode 100644 index 000000000..88be7a258 --- /dev/null +++ b/cockatrice/src/server/user/user_list_manager.h @@ -0,0 +1,72 @@ +#ifndef COCKATRICE_USER_LIST_MANAGER_H +#define COCKATRICE_USER_LIST_MANAGER_H + +#include "../chat_view/user_list_proxy.h" +#include "pb/serverinfo_user.pb.h" + +#include +#include + +class AbstractClient; +class Event_AddToList; +class Event_ListRooms; +class Event_RemoveFromList; +class Event_UserJoined; +class Event_UserLeft; +class Response; +class ServerInfo_User; +class TabSupervisor; + +class UserListManager : public QWidget, public UserlistProxy +{ + Q_OBJECT + +private: + AbstractClient *client; + ServerInfo_User *ownUserInfo; + QMap onlineUsers, buddyUsers, ignoredUsers; + +private slots: + void setOwnUserInfo(const ServerInfo_User &userInfo); + void populateInitialOnlineUsers(); + void processListUsersResponse(const Response &response); + void processUserJoinedEvent(const Event_UserJoined &event); + void processUserLeftEvent(const Event_UserLeft &event); + void buddyListReceived(const QList &_buddyList); + void ignoreListReceived(const QList &_ignoreList); + void processAddToListEvent(const Event_AddToList &event); + void processRemoveFromListEvent(const Event_RemoveFromList &event); + +public: + explicit UserListManager(AbstractClient *_client, QWidget *parent = nullptr); + ~UserListManager() override; + + [[nodiscard]] QMap getAllUsersList() const + { + return onlineUsers; + } + [[nodiscard]] QMap getBuddyList() const + { + return buddyUsers; + } + [[nodiscard]] QMap getIgnoreList() const + { + return ignoredUsers; + } + + bool isOwnUserRegistered() const override; + QString getOwnUsername() const override; + bool isUserBuddy(const QString &userName) const override; + bool isUserIgnored(const QString &userName) const override; + const ServerInfo_User *getOnlineUser(const QString &userName) const override; + +public slots: + void handleConnect(); + void handleDisconnect(); + +signals: + void userLeft(const QString &userName); + void userJoined(const ServerInfo_User &userInfo); +}; + +#endif // COCKATRICE_USER_LIST_MANAGER_H diff --git a/cockatrice/src/server/user/user_list_widget.cpp b/cockatrice/src/server/user/user_list_widget.cpp index 80fe67b50..a2f610a63 100644 --- a/cockatrice/src/server/user/user_list_widget.cpp +++ b/cockatrice/src/server/user/user_list_widget.cpp @@ -5,6 +5,7 @@ #include "../../client/tabs/tab_supervisor.h" #include "../../client/ui/pixel_map_generator.h" #include "../../game/game_selector.h" +#include "../../server/user/user_list_manager.h" #include "../pending_command.h" #include "pb/moderator_commands.pb.h" #include "pb/response_get_games_of_user.pb.h" @@ -377,7 +378,7 @@ UserListWidget::UserListWidget(TabSupervisor *_tabSupervisor, : QGroupBox(parent), tabSupervisor(_tabSupervisor), client(_client), type(_type), onlineCount(0) { itemDelegate = new UserListItemDelegate(this); - userContextMenu = new UserContextMenu(tabSupervisor, this); + userContextMenu = new UserContextMenu(tabSupervisor, tabSupervisor->getUserListManager(), this); connect(userContextMenu, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool))); userTree = new QTreeWidget;