mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-14 19:18:55 -07:00
fix segfault that happens when account tab is closed (#5474)
This commit is contained in:
parent
d09b9eb533
commit
23bd18a04c
19 changed files with 332 additions and 121 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 <QtGui>
|
||||
#include <QtWidgets>
|
||||
|
||||
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<WarningDialog *>(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);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
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,
|
||||
|
|
|
|||
170
cockatrice/src/server/user/user_list_manager.cpp
Normal file
170
cockatrice/src/server/user/user_list_manager.cpp
Normal file
|
|
@ -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<const Response &, const CommandContainer &, const QVariant &>(&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<ServerInfo_User> &_buddyList)
|
||||
{
|
||||
for (const auto &user : _buddyList) {
|
||||
const auto &userName = QString::fromStdString(user.name());
|
||||
buddyUsers.insert(userName, user);
|
||||
}
|
||||
}
|
||||
|
||||
void UserListManager::ignoreListReceived(const QList<ServerInfo_User> &_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<QString, ServerInfo_User> 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<QString, ServerInfo_User> 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;
|
||||
};
|
||||
72
cockatrice/src/server/user/user_list_manager.h
Normal file
72
cockatrice/src/server/user/user_list_manager.h
Normal file
|
|
@ -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 <QMap>
|
||||
#include <QWidget>
|
||||
|
||||
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<QString, ServerInfo_User> 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<ServerInfo_User> &_buddyList);
|
||||
void ignoreListReceived(const QList<ServerInfo_User> &_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<QString, ServerInfo_User> getAllUsersList() const
|
||||
{
|
||||
return onlineUsers;
|
||||
}
|
||||
[[nodiscard]] QMap<QString, ServerInfo_User> getBuddyList() const
|
||||
{
|
||||
return buddyUsers;
|
||||
}
|
||||
[[nodiscard]] QMap<QString, ServerInfo_User> 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue