From 5f0e18923838ce8c49c54593d2378e3df71826bb Mon Sep 17 00:00:00 2001 From: adityaruplaha Date: Mon, 30 Apr 2018 13:10:51 +0530 Subject: [PATCH] Add Support for Room Descriptions --- src/citra_qt/configuration/config.cpp | 2 ++ src/citra_qt/multiplayer/client_room.cpp | 1 + src/citra_qt/multiplayer/client_room.ui | 7 +++++++ src/citra_qt/multiplayer/host_room.cpp | 8 ++++++-- src/citra_qt/multiplayer/host_room.ui | 16 ++++++++++++++- src/citra_qt/multiplayer/lobby.cpp | 10 ++++++--- src/citra_qt/multiplayer/lobby_p.h | 25 +++++++++++++++++++++++ src/citra_qt/ui_settings.h | 1 + src/common/announce_multiplayer_room.h | 8 ++++++-- src/core/announce_multiplayer_session.cpp | 9 ++++---- src/dedicated_room/citra-room.cpp | 12 ++++++++--- src/network/room.cpp | 10 ++++++--- src/network/room.h | 6 ++++-- src/network/room_member.cpp | 2 ++ src/web_service/announce_room_json.cpp | 11 +++++++++- src/web_service/announce_room_json.h | 5 +++-- 16 files changed, 110 insertions(+), 23 deletions(-) diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index d696ed98d9..5a69a2d305 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -329,6 +329,7 @@ void Config::ReadValues() { } UISettings::values.max_player = ReadSetting("max_player", 8).toUInt(); UISettings::values.game_id = ReadSetting("game_id", 0).toULongLong(); + UISettings::values.room_description = ReadSetting("room_description", "").toString(); qt_config->endGroup(); qt_config->endGroup(); @@ -533,6 +534,7 @@ void Config::SaveValues() { WriteSetting("host_type", UISettings::values.host_type, 0); WriteSetting("max_player", UISettings::values.max_player, 8); WriteSetting("game_id", UISettings::values.game_id, 0); + WriteSetting("room_description", UISettings::values.room_description, ""); qt_config->endGroup(); qt_config->endGroup(); diff --git a/src/citra_qt/multiplayer/client_room.cpp b/src/citra_qt/multiplayer/client_room.cpp index 63227f6e0a..3c18cc4747 100644 --- a/src/citra_qt/multiplayer/client_room.cpp +++ b/src/citra_qt/multiplayer/client_room.cpp @@ -82,6 +82,7 @@ void ClientRoomWindow::UpdateView() { .arg(QString::fromStdString(information.name)) .arg(memberlist.size()) .arg(information.member_slots)); + ui->description->setText(QString::fromStdString(information.description)); return; } } diff --git a/src/citra_qt/multiplayer/client_room.ui b/src/citra_qt/multiplayer/client_room.ui index d83c088c27..35086ab284 100644 --- a/src/citra_qt/multiplayer/client_room.ui +++ b/src/citra_qt/multiplayer/client_room.ui @@ -21,6 +21,13 @@ 0 + + + + Room Description + + + diff --git a/src/citra_qt/multiplayer/host_room.cpp b/src/citra_qt/multiplayer/host_room.cpp index fa335bfaed..13ccdd95a1 100644 --- a/src/citra_qt/multiplayer/host_room.cpp +++ b/src/citra_qt/multiplayer/host_room.cpp @@ -70,6 +70,7 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list, if (index != -1) { ui->game_list->setCurrentIndex(index); } + ui->room_description->setText(UISettings::values.room_description); } HostRoomWindow::~HostRoomWindow() = default; @@ -108,8 +109,10 @@ void HostRoomWindow::Host() { auto port = ui->port->isModified() ? ui->port->text().toInt() : Network::DefaultRoomPort; auto password = ui->password->text().toStdString(); if (auto room = Network::GetRoom().lock()) { - bool created = room->Create(ui->room_name->text().toStdString(), "", port, password, - ui->max_player->value(), game_name.toStdString(), game_id); + bool created = + room->Create(ui->room_name->text().toStdString(), + ui->room_description->toPlainText().toStdString(), "", port, password, + ui->max_player->value(), game_name.toStdString(), game_id); if (!created) { NetworkMessage::ShowError(NetworkMessage::COULD_NOT_CREATE_ROOM); LOG_ERROR(Network, "Could not create room!"); @@ -132,6 +135,7 @@ void HostRoomWindow::Host() { UISettings::values.room_port = (ui->port->isModified() && !ui->port->text().isEmpty()) ? ui->port->text() : QString::number(Network::DefaultRoomPort); + UISettings::values.room_description = ui->room_description->toPlainText(); Settings::Apply(); OnConnection(); } diff --git a/src/citra_qt/multiplayer/host_room.ui b/src/citra_qt/multiplayer/host_room.ui index 68bfdb0daf..5084ef7f42 100644 --- a/src/citra_qt/multiplayer/host_room.ui +++ b/src/citra_qt/multiplayer/host_room.ui @@ -7,7 +7,7 @@ 0 0 607 - 165 + 211 @@ -131,6 +131,20 @@ + + + + + + Room Description + + + + + + + + diff --git a/src/citra_qt/multiplayer/lobby.cpp b/src/citra_qt/multiplayer/lobby.cpp index 6b22c277c0..1c23c8cef2 100644 --- a/src/citra_qt/multiplayer/lobby.cpp +++ b/src/citra_qt/multiplayer/lobby.cpp @@ -212,7 +212,11 @@ void Lobby::OnRefreshLobby() { // To make the rows expandable, add the member data as a child of the first column of the // rows with people in them and have qt set them to colspan after the model is finished // resetting - if (room.members.size() > 0) { + if (!room.description.empty()) { + first_item->appendRow( + new LobbyItemDescription(QString::fromStdString(room.description))); + } + if (!room.members.empty()) { first_item->appendRow(new LobbyItemExpandedMemberList(members)); } } @@ -228,8 +232,8 @@ void Lobby::OnRefreshLobby() { // Set the member list child items to span all columns for (int i = 0; i < proxy->rowCount(); i++) { auto parent = model->item(i, 0); - if (parent->hasChildren()) { - ui->room_list->setFirstColumnSpanned(0, proxy->index(i, 0), true); + for (int j = 0; j < parent->rowCount(); j++) { + ui->room_list->setFirstColumnSpanned(j, proxy->index(i, 0), true); } } } diff --git a/src/citra_qt/multiplayer/lobby_p.h b/src/citra_qt/multiplayer/lobby_p.h index 3773f99deb..7fe20b78b6 100644 --- a/src/citra_qt/multiplayer/lobby_p.h +++ b/src/citra_qt/multiplayer/lobby_p.h @@ -55,6 +55,31 @@ public: } }; +class LobbyItemDescription : public LobbyItem { +public: + static const int DescriptionRole = Qt::UserRole + 1; + + LobbyItemDescription() = default; + explicit LobbyItemDescription(QString description) { + setData(description, DescriptionRole); + } + + QVariant data(int role) const override { + if (role != Qt::DisplayRole) { + return LobbyItem::data(role); + } + auto description = data(DescriptionRole).toString(); + description.prepend("Description: "); + return description; + } + + bool operator<(const QStandardItem& other) const override { + return data(DescriptionRole) + .toString() + .localeAwareCompare(other.data(DescriptionRole).toString()) < 0; + } +}; + class LobbyItemGame : public LobbyItem { public: static const int TitleIDRole = Qt::UserRole + 1; diff --git a/src/citra_qt/ui_settings.h b/src/citra_qt/ui_settings.h index 1e09dd7e8f..b26d693644 100644 --- a/src/citra_qt/ui_settings.h +++ b/src/citra_qt/ui_settings.h @@ -109,6 +109,7 @@ struct Values { QString room_port; uint host_type; qulonglong game_id; + QString room_description; // logging bool show_console; diff --git a/src/common/announce_multiplayer_room.h b/src/common/announce_multiplayer_room.h index 5f9fc8ec26..21f8c5a08e 100644 --- a/src/common/announce_multiplayer_room.h +++ b/src/common/announce_multiplayer_room.h @@ -23,6 +23,7 @@ struct Room { u64 game_id; }; std::string name; + std::string description; std::string UID; std::string owner; std::string ip; @@ -49,13 +50,15 @@ public: * Sets the Information that gets used for the announce * @param uid The Id of the room * @param name The name of the room + * @param description The room description * @param port The port of the room * @param net_version The version of the libNetwork that gets used * @param has_password True if the room is passowrd protected * @param preferred_game The preferred game of the room * @param preferred_game_id The title id of the preferred game */ - virtual void SetRoomInformation(const std::string& uid, const std::string& name, const u16 port, + virtual void SetRoomInformation(const std::string& uid, const std::string& name, + const std::string& description, const u16 port, const u32 max_player, const u32 net_version, const bool has_password, const std::string& preferred_game, const u64 preferred_game_id) = 0; @@ -100,7 +103,8 @@ class NullBackend : public Backend { public: ~NullBackend() = default; void SetRoomInformation(const std::string& /*uid*/, const std::string& /*name*/, - const u16 /*port*/, const u32 /*max_player*/, const u32 /*net_version*/, + const std::string& /*description*/, const u16 /*port*/, + const u32 /*max_player*/, const u32 /*net_version*/, const bool /*has_password*/, const std::string& /*preferred_game*/, const u64 /*preferred_game_id*/) override {} void AddPlayer(const std::string& /*nickname*/, const MacAddress& /*mac_address*/, diff --git a/src/core/announce_multiplayer_session.cpp b/src/core/announce_multiplayer_session.cpp index 69dbf6fcee..3d2301e0f0 100644 --- a/src/core/announce_multiplayer_session.cpp +++ b/src/core/announce_multiplayer_session.cpp @@ -78,10 +78,11 @@ void AnnounceMultiplayerSession::AnnounceMultiplayerLoop() { } Network::RoomInformation room_information = room->GetRoomInformation(); std::vector memberlist = room->GetRoomMemberList(); - backend->SetRoomInformation( - room_information.uid, room_information.name, room_information.port, - room_information.member_slots, Network::network_version, room->HasPassword(), - room_information.preferred_game, room_information.preferred_game_id); + backend->SetRoomInformation(room_information.uid, room_information.name, + room_information.description, room_information.port, + room_information.member_slots, Network::network_version, + room->HasPassword(), room_information.preferred_game, + room_information.preferred_game_id); backend->ClearPlayers(); for (const auto& member : memberlist) { backend->AddPlayer(member.nickname, member.mac_address, member.game_info.id, diff --git a/src/dedicated_room/citra-room.cpp b/src/dedicated_room/citra-room.cpp index 7d23c93f21..8ccce245da 100644 --- a/src/dedicated_room/citra-room.cpp +++ b/src/dedicated_room/citra-room.cpp @@ -36,6 +36,7 @@ static void PrintHelp(const char* argv0) { std::cout << "Usage: " << argv0 << " [options] \n" "--room-name The name of the room\n" + "--room-description The room description\n" "--port The port used for the room\n" "--max_members The maximum number of players for this room\n" "--password The password for the room\n" @@ -63,6 +64,7 @@ int main(int argc, char** argv) { gladLoadGL(); std::string room_name; + std::string room_description; std::string password; std::string preferred_game; std::string username; @@ -74,6 +76,7 @@ int main(int argc, char** argv) { static struct option long_options[] = { {"room-name", required_argument, 0, 'n'}, + {"room-description", required_argument, 0, 'd'}, {"port", required_argument, 0, 'p'}, {"max_members", required_argument, 0, 'm'}, {"password", required_argument, 0, 'w'}, @@ -88,12 +91,15 @@ int main(int argc, char** argv) { }; while (optind < argc) { - char arg = getopt_long(argc, argv, "n:p:m:w:g:u:t:a:i:hv", long_options, &option_index); + char arg = getopt_long(argc, argv, "n:d:p:m:w:g:u:t:a:i:hv", long_options, &option_index); if (arg != -1) { switch (arg) { case 'n': room_name.assign(optarg); break; + case 'd': + room_description.assign(optarg); + break; case 'p': port = strtoul(optarg, &endarg, 0); break; @@ -175,8 +181,8 @@ int main(int argc, char** argv) { Network::Init(); if (std::shared_ptr room = Network::GetRoom().lock()) { - if (!room->Create(room_name, "", port, password, max_members, preferred_game, - preferred_game_id)) { + if (!room->Create(room_name, room_description, "", port, password, max_members, + preferred_game, preferred_game_id)) { std::cout << "Failed to create room: \n\n"; return -1; } diff --git a/src/network/room.cpp b/src/network/room.cpp index 9ae26f524b..c5b9609256 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp @@ -124,6 +124,7 @@ public: * The packet has the structure: * ID_ROOM_INFORMATION * room_name + * room_description * member_slots: The max number of clients allowed in this room * uid * port @@ -404,6 +405,7 @@ void Room::RoomImpl::BroadcastRoomInformation() { Packet packet; packet << static_cast(IdRoomInformation); packet << room_information.name; + packet << room_information.description; packet << room_information.member_slots; packet << room_information.uid; packet << room_information.port; @@ -584,9 +586,10 @@ Room::Room() : room_impl{std::make_unique()} {} Room::~Room() = default; -bool Room::Create(const std::string& name, const std::string& server_address, u16 server_port, - const std::string& password, const u32 max_connections, - const std::string& preferred_game, u64 preferred_game_id) { +bool Room::Create(const std::string& name, const std::string& description, + const std::string& server_address, u16 server_port, const std::string& password, + const u32 max_connections, const std::string& preferred_game, + u64 preferred_game_id) { ENetAddress address; address.host = ENET_HOST_ANY; if (!server_address.empty()) { @@ -603,6 +606,7 @@ bool Room::Create(const std::string& name, const std::string& server_address, u1 room_impl->state = State::Open; room_impl->room_information.name = name; + room_impl->room_information.description = description; room_impl->room_information.member_slots = max_connections; room_impl->room_information.port = server_port; room_impl->room_information.preferred_game = preferred_game; diff --git a/src/network/room.h b/src/network/room.h index 7a73022bcb..9b2889a0cd 100644 --- a/src/network/room.h +++ b/src/network/room.h @@ -25,6 +25,7 @@ constexpr std::size_t NumChannels = 1; // Number of channels used for the connec struct RoomInformation { std::string name; ///< Name of the server + std::string description; ///< Server description u32 member_slots; ///< Maximum number of members in this room std::string uid; ///< The unique ID of the room u16 port; ///< The port of this room @@ -103,8 +104,9 @@ public: * Creates the socket for this room. Will bind to default address if * server is empty string. */ - bool Create(const std::string& name, const std::string& server = "", - u16 server_port = DefaultRoomPort, const std::string& password = "", + bool Create(const std::string& name, const std::string& description = "", + const std::string& server = "", u16 server_port = DefaultRoomPort, + const std::string& password = "", const u32 max_connections = MaxConcurrentConnections, const std::string& preferred_game = "", u64 preferred_game_id = 0); diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp index 682821aa3b..14fc201f50 100644 --- a/src/network/room_member.cpp +++ b/src/network/room_member.cpp @@ -230,11 +230,13 @@ void RoomMember::RoomMemberImpl::HandleRoomInformationPacket(const ENetEvent* ev RoomInformation info{}; packet >> info.name; + packet >> info.description; packet >> info.member_slots; packet >> info.uid; packet >> info.port; packet >> info.preferred_game; room_information.name = info.name; + room_information.description = info.description; room_information.member_slots = info.member_slots; room_information.port = info.port; room_information.preferred_game = info.preferred_game; diff --git a/src/web_service/announce_room_json.cpp b/src/web_service/announce_room_json.cpp index c0d543e738..970c5e0b65 100644 --- a/src/web_service/announce_room_json.cpp +++ b/src/web_service/announce_room_json.cpp @@ -27,6 +27,7 @@ void to_json(nlohmann::json& json, const Room& room) { json["id"] = room.UID; json["port"] = room.port; json["name"] = room.name; + json["description"] = room.description; json["preferredGameName"] = room.preferred_game; json["preferredGameId"] = room.preferred_game_id; json["maxPlayers"] = room.max_player; @@ -41,6 +42,12 @@ void to_json(nlohmann::json& json, const Room& room) { void from_json(const nlohmann::json& json, Room& room) { room.ip = json.at("address").get(); room.name = json.at("name").get(); + try { + room.description = json.at("description").get(); + } catch (const nlohmann::detail::out_of_range& e) { + room.description = ""; + LOG_DEBUG(Network, "Room \'{}\' doesn't contain a description", room.name); + } room.owner = json.at("owner").get(); room.port = json.at("port").get(); room.preferred_game = json.at("preferredGameName").get(); @@ -59,11 +66,13 @@ void from_json(const nlohmann::json& json, Room& room) { namespace WebService { -void RoomJson::SetRoomInformation(const std::string& uid, const std::string& name, const u16 port, +void RoomJson::SetRoomInformation(const std::string& uid, const std::string& name, + const std::string& description, const u16 port, const u32 max_player, const u32 net_version, const bool has_password, const std::string& preferred_game, const u64 preferred_game_id) { room.name = name; + room.description = description; room.UID = uid; room.port = port; room.max_player = max_player; diff --git a/src/web_service/announce_room_json.h b/src/web_service/announce_room_json.h index 7356052130..57152c243b 100644 --- a/src/web_service/announce_room_json.h +++ b/src/web_service/announce_room_json.h @@ -20,8 +20,9 @@ public: RoomJson(const std::string& host, const std::string& username, const std::string& token) : client(host, username, token), host(host), username(username), token(token) {} ~RoomJson() = default; - void SetRoomInformation(const std::string& uid, const std::string& name, const u16 port, - const u32 max_player, const u32 net_version, const bool has_password, + void SetRoomInformation(const std::string& uid, const std::string& name, + const std::string& description, const u16 port, const u32 max_player, + const u32 net_version, const bool has_password, const std::string& preferred_game, const u64 preferred_game_id) override; void AddPlayer(const std::string& nickname,