diff --git a/src/citra_qt/multiplayer/chat_room.cpp b/src/citra_qt/multiplayer/chat_room.cpp index ff12b3f1a..94dc6c357 100644 --- a/src/citra_qt/multiplayer/chat_room.cpp +++ b/src/citra_qt/multiplayer/chat_room.cpp @@ -160,6 +160,10 @@ ChatRoom::ChatRoom(QWidget* parent) : QWidget(parent), ui(std::make_uniqueretranslateUi(this); } @@ -177,6 +181,21 @@ void ChatRoom::AppendChatMessage(const QString& msg) { ui->chat_history->append(msg); } +void ChatRoom::SendModerationRequest(Network::RoomMessageTypes type, const std::string& nickname) { + if (auto room = Network::GetRoomMember().lock()) { + auto members = room->GetMemberInformation(); + auto it = std::find_if(members.begin(), members.end(), + [&nickname](const Network::RoomMember::MemberInformation& member) { + return member.nickname == nickname; + }); + if (it == members.end()) { + NetworkMessage::ShowError(NetworkMessage::NO_SUCH_USER); + return; + } + room->SendModerationRequest(type, nickname); + } +} + bool ChatRoom::ValidateMessage(const std::string& msg) { return !msg.empty(); } @@ -241,6 +260,15 @@ void ChatRoom::OnStatusMessageReceive(const Network::StatusMessageEntry& status_ case Network::IdMemberLeave: message = tr("%1 has left").arg(name); break; + case Network::IdMemberKicked: + message = tr("%1 has been kicked").arg(name); + break; + case Network::IdMemberBanned: + message = tr("%1 has been banned").arg(name); + break; + case Network::IdAddressUnbanned: + message = tr("%1 has been unbanned").arg(name); + break; } if (!message.isEmpty()) AppendStatusMessage(message); @@ -351,7 +379,7 @@ void ChatRoom::PopupContextMenu(const QPoint& menu_location) { std::string nickname = player_list->item(item.row())->data(PlayerListItem::NicknameRole).toString().toStdString(); if (auto room = Network::GetRoomMember().lock()) { - // You can't block yourself + // You can't block, kick or ban yourself if (nickname == room->GetNickname()) return; } @@ -377,5 +405,32 @@ void ChatRoom::PopupContextMenu(const QPoint& menu_location) { } }); + if (has_mod_perms) { + context_menu.addSeparator(); + + QAction* kick_action = context_menu.addAction(tr("Kick")); + QAction* ban_action = context_menu.addAction(tr("Ban")); + + connect(kick_action, &QAction::triggered, [this, nickname] { + QMessageBox::StandardButton result = + QMessageBox::question(this, tr("Kick Player"), + tr("Are you sure you would like to kick %1?") + .arg(QString::fromStdString(nickname)), + QMessageBox::Yes | QMessageBox::No); + if (result == QMessageBox::Yes) + SendModerationRequest(Network::IdModKick, nickname); + }); + connect(ban_action, &QAction::triggered, [this, nickname] { + QMessageBox::StandardButton result = QMessageBox::question( + this, tr("Ban Player"), + tr("Are you sure you would like to kick and ban %1?\n\nThis would " + "ban both their forum username and their IP address.") + .arg(QString::fromStdString(nickname)), + QMessageBox::Yes | QMessageBox::No); + if (result == QMessageBox::Yes) + SendModerationRequest(Network::IdModBan, nickname); + }); + } + context_menu.exec(ui->player_view->viewport()->mapToGlobal(menu_location)); } diff --git a/src/citra_qt/multiplayer/chat_room.h b/src/citra_qt/multiplayer/chat_room.h index 7a7c84b48..58cb25e83 100644 --- a/src/citra_qt/multiplayer/chat_room.h +++ b/src/citra_qt/multiplayer/chat_room.h @@ -36,6 +36,8 @@ public: void AppendStatusMessage(const QString& msg); ~ChatRoom(); + void SetModPerms(bool is_mod); + public slots: void OnRoomUpdate(const Network::RoomInformation& info); void OnChatReceive(const Network::ChatEntry&); @@ -54,8 +56,10 @@ private: static constexpr u32 max_chat_lines = 1000; void AppendChatMessage(const QString&); bool ValidateMessage(const std::string&); + void SendModerationRequest(Network::RoomMessageTypes type, const std::string& nickname); void UpdateIconDisplay(); + bool has_mod_perms = false; QStandardItemModel* player_list; std::unique_ptr ui; std::unordered_set block_list; @@ -66,3 +70,4 @@ Q_DECLARE_METATYPE(Network::ChatEntry); Q_DECLARE_METATYPE(Network::StatusMessageEntry); Q_DECLARE_METATYPE(Network::RoomInformation); Q_DECLARE_METATYPE(Network::RoomMember::State); +Q_DECLARE_METATYPE(Network::RoomMember::Error); diff --git a/src/citra_qt/multiplayer/client_room.cpp b/src/citra_qt/multiplayer/client_room.cpp index 54b4dc55e..84a425189 100644 --- a/src/citra_qt/multiplayer/client_room.cpp +++ b/src/citra_qt/multiplayer/client_room.cpp @@ -55,6 +55,7 @@ ClientRoomWindow::ClientRoomWindow(QWidget* parent) ClientRoomWindow::~ClientRoomWindow() = default; void ClientRoomWindow::SetModPerms(bool is_mod) { + ui->chat->SetModPerms(is_mod); ui->moderation->setVisible(is_mod); ui->moderation->setDefault(false); ui->moderation->setAutoDefault(false);