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,