From 6c8e45618578de1406c0bf4a7f976bd4903c339c Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Fri, 15 Jul 2022 19:45:35 +0200 Subject: [PATCH] Address first part of review comments --- .gitmodules | 3 + externals/CMakeLists.txt | 5 + src/core/CMakeLists.txt | 10 +- src/input_common/helpers/udp_protocol.h | 2 +- src/network/room.h | 2 +- src/web_service/CMakeLists.txt | 4 +- src/web_service/verify_user_jwt.cpp | 60 ++++++++++ src/web_service/verify_user_jwt.h | 25 ++++ src/yuzu/CMakeLists.txt | 4 + src/yuzu/configuration/config.cpp | 148 ++++++++++++------------ src/yuzu/multiplayer/chat_room.cpp | 2 +- src/yuzu/multiplayer/direct_connect.cpp | 20 ++-- src/yuzu/multiplayer/host_room.cpp | 45 +++---- src/yuzu/multiplayer/lobby.cpp | 18 +-- src/yuzu/multiplayer/state.cpp | 2 +- src/yuzu/uisettings.h | 22 ++-- 16 files changed, 239 insertions(+), 133 deletions(-) create mode 100644 src/web_service/verify_user_jwt.cpp create mode 100644 src/web_service/verify_user_jwt.h diff --git a/.gitmodules b/.gitmodules index d8e04923a..26c6735cd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -46,3 +46,6 @@ [submodule "vcpkg"] path = externals/vcpkg url = https://github.com/Microsoft/vcpkg.git +[submodule "cpp-jwt"] + path = externals/cpp-jwt + url = https://github.com/arun11299/cpp-jwt.git diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index b4570bb69..5b74a1773 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -116,6 +116,11 @@ if (ENABLE_WEB_SERVICE) if (WIN32) target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32) endif() + + # cpp-jwt + add_library(cpp-jwt INTERFACE) + target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include) + target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON) endif() # Opus diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 48f5c1ee0..c1cc62a45 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -716,6 +716,11 @@ add_library(core STATIC hle/service/vi/vi_u.h hle/service/wlan/wlan.cpp hle/service/wlan/wlan.h + internal_network/network.cpp + internal_network/network.h + internal_network/network_interface.cpp + internal_network/network_interface.h + internal_network/sockets.h loader/deconstructed_rom_directory.cpp loader/deconstructed_rom_directory.h loader/elf.cpp @@ -743,11 +748,6 @@ add_library(core STATIC memory/dmnt_cheat_vm.h memory.cpp memory.h - internal_network/network.cpp - internal_network/network.h - internal_network/network_interface.cpp - internal_network/network_interface.h - internal_network/sockets.h perf_stats.cpp perf_stats.h reporter.cpp diff --git a/src/input_common/helpers/udp_protocol.h b/src/input_common/helpers/udp_protocol.h index 597f51cd3..889693e73 100644 --- a/src/input_common/helpers/udp_protocol.h +++ b/src/input_common/helpers/udp_protocol.h @@ -85,7 +85,7 @@ enum RegisterFlags : u8 { struct Version {}; /** * Requests the server to send information about what controllers are plugged into the ports - * In citra's case, we only have one controller, so for simplicity's sake, we can just send a + * In yuzu's case, we only have one controller, so for simplicity's sake, we can just send a * request explicitly for the first controller port and leave it at that. In the future it would be * nice to make this configurable */ diff --git a/src/network/room.h b/src/network/room.h index 5d4371c16..df2253bf8 100644 --- a/src/network/room.h +++ b/src/network/room.h @@ -13,7 +13,7 @@ namespace Network { -constexpr u32 network_version = 4; ///< The version of this Room and RoomMember +constexpr u32 network_version = 1; ///< The version of this Room and RoomMember constexpr u16 DefaultRoomPort = 24872; diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt index aff81f26d..753fb6e7a 100644 --- a/src/web_service/CMakeLists.txt +++ b/src/web_service/CMakeLists.txt @@ -5,10 +5,12 @@ add_library(web_service STATIC telemetry_json.h verify_login.cpp verify_login.h + verify_user_jwt.cpp + verify_user_jwt.h web_backend.cpp web_backend.h web_result.h ) create_target_directory_groups(web_service) -target_link_libraries(web_service PRIVATE common network nlohmann_json::nlohmann_json httplib) +target_link_libraries(web_service PRIVATE common network nlohmann_json::nlohmann_json httplib cpp-jwt) diff --git a/src/web_service/verify_user_jwt.cpp b/src/web_service/verify_user_jwt.cpp new file mode 100644 index 000000000..78fe7bed5 --- /dev/null +++ b/src/web_service/verify_user_jwt.cpp @@ -0,0 +1,60 @@ +// Copyright 2018 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include "common/logging/log.h" +#include "web_service/verify_user_jwt.h" +#include "web_service/web_backend.h" +#include "web_service/web_result.h" + +namespace WebService { + +static std::string public_key; +std::string GetPublicKey(const std::string& host) { + if (public_key.empty()) { + Client client(host, "", ""); // no need for credentials here + public_key = client.GetPlain("/jwt/external/key.pem", true).returned_data; + if (public_key.empty()) { + LOG_ERROR(WebService, "Could not fetch external JWT public key, verification may fail"); + } else { + LOG_INFO(WebService, "Fetched external JWT public key (size={})", public_key.size()); + } + } + return public_key; +} + +VerifyUserJWT::VerifyUserJWT(const std::string& host) : pub_key(GetPublicKey(host)) {} + +Network::VerifyUser::UserData VerifyUserJWT::LoadUserData(const std::string& verify_UID, + const std::string& token) { + const std::string audience = fmt::format("external-{}", verify_UID); + using namespace jwt::params; + std::error_code error; + auto decoded = + jwt::decode(token, algorithms({"rs256"}), error, secret(pub_key), issuer("yuzu-core"), + aud(audience), validate_iat(true), validate_jti(true)); + if (error) { + LOG_INFO(WebService, "Verification failed: category={}, code={}, message={}", + error.category().name(), error.value(), error.message()); + return {}; + } + Network::VerifyUser::UserData user_data{}; + if (decoded.payload().has_claim("username")) { + user_data.username = decoded.payload().get_claim_value("username"); + } + if (decoded.payload().has_claim("displayName")) { + user_data.display_name = decoded.payload().get_claim_value("displayName"); + } + if (decoded.payload().has_claim("avatarUrl")) { + user_data.avatar_url = decoded.payload().get_claim_value("avatarUrl"); + } + if (decoded.payload().has_claim("roles")) { + auto roles = decoded.payload().get_claim_value>("roles"); + user_data.moderator = std::find(roles.begin(), roles.end(), "moderator") != roles.end(); + } + return user_data; +} + +} // namespace WebService diff --git a/src/web_service/verify_user_jwt.h b/src/web_service/verify_user_jwt.h new file mode 100644 index 000000000..826e01eed --- /dev/null +++ b/src/web_service/verify_user_jwt.h @@ -0,0 +1,25 @@ +// Copyright 2018 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include "network/verify_user.h" +#include "web_service/web_backend.h" + +namespace WebService { + +class VerifyUserJWT final : public Network::VerifyUser::Backend { +public: + VerifyUserJWT(const std::string& host); + ~VerifyUserJWT() = default; + + Network::VerifyUser::UserData LoadUserData(const std::string& verify_UID, + const std::string& token) override; + +private: + std::string pub_key; +}; + +} // namespace WebService diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index f3cad8f31..66873143e 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -326,6 +326,10 @@ if (USE_DISCORD_PRESENCE) target_compile_definitions(yuzu PRIVATE -DUSE_DISCORD_PRESENCE) endif() +if (ENABLE_WEB_SERVICE) + target_compile_definitions(yuzu PRIVATE -DENABLE_WEB_SERVICE) +endif() + if (YUZU_USE_QT_WEB_ENGINE) target_link_libraries(yuzu PRIVATE Qt::WebEngineCore Qt::WebEngineWidgets) target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_WEB_ENGINE) diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 7c11e2c03..3b22102a8 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -585,48 +585,6 @@ void Config::ReadMiscellaneousValues() { qt_config->endGroup(); } -void Config::ReadMultiplayerValues() { - qt_config->beginGroup(QStringLiteral("Multiplayer")); - - UISettings::values.nickname = ReadSetting(QStringLiteral("nickname"), QString{}).toString(); - UISettings::values.ip = ReadSetting(QStringLiteral("ip"), QString{}).toString(); - UISettings::values.port = - ReadSetting(QStringLiteral("port"), Network::DefaultRoomPort).toString(); - UISettings::values.room_nickname = - ReadSetting(QStringLiteral("room_nickname"), QString{}).toString(); - UISettings::values.room_name = ReadSetting(QStringLiteral("room_name"), QString{}).toString(); - UISettings::values.room_port = - ReadSetting(QStringLiteral("room_port"), QStringLiteral("24872")).toString(); - bool ok; - UISettings::values.host_type = ReadSetting(QStringLiteral("host_type"), 0).toUInt(&ok); - if (!ok) { - UISettings::values.host_type = 0; - } - UISettings::values.max_player = ReadSetting(QStringLiteral("max_player"), 8).toUInt(); - UISettings::values.game_id = ReadSetting(QStringLiteral("game_id"), 0).toULongLong(); - UISettings::values.room_description = - ReadSetting(QStringLiteral("room_description"), QString{}).toString(); - // Read ban list back - int size = qt_config->beginReadArray(QStringLiteral("username_ban_list")); - UISettings::values.ban_list.first.resize(size); - for (int i = 0; i < size; ++i) { - qt_config->setArrayIndex(i); - UISettings::values.ban_list.first[i] = - ReadSetting(QStringLiteral("username")).toString().toStdString(); - } - qt_config->endArray(); - size = qt_config->beginReadArray(QStringLiteral("ip_ban_list")); - UISettings::values.ban_list.second.resize(size); - for (int i = 0; i < size; ++i) { - qt_config->setArrayIndex(i); - UISettings::values.ban_list.second[i] = - ReadSetting(QStringLiteral("ip")).toString().toStdString(); - } - qt_config->endArray(); - - qt_config->endGroup(); -} - void Config::ReadPathValues() { qt_config->beginGroup(QStringLiteral("Paths")); @@ -904,6 +862,42 @@ void Config::ReadWebServiceValues() { qt_config->endGroup(); } +void Config::ReadMultiplayerValues() { + qt_config->beginGroup(QStringLiteral("Multiplayer")); + + ReadBasicSetting(UISettings::values.multiplayer_nickname); + ReadBasicSetting(UISettings::values.multiplayer_ip); + ReadBasicSetting(UISettings::values.multiplayer_port); + ReadBasicSetting(UISettings::values.multiplayer_room_nickname); + ReadBasicSetting(UISettings::values.multiplayer_room_name); + ReadBasicSetting(UISettings::values.multiplayer_room_port); + ReadBasicSetting(UISettings::values.multiplayer_host_type); + ReadBasicSetting(UISettings::values.multiplayer_port); + ReadBasicSetting(UISettings::values.multiplayer_max_player); + ReadBasicSetting(UISettings::values.multiplayer_game_id); + ReadBasicSetting(UISettings::values.multiplayer_room_description); + + // Read ban list back + int size = qt_config->beginReadArray(QStringLiteral("username_ban_list")); + UISettings::values.multiplayer_ban_list.first.resize(size); + for (int i = 0; i < size; ++i) { + qt_config->setArrayIndex(i); + UISettings::values.multiplayer_ban_list.first[i] = + ReadSetting(QStringLiteral("username")).toString().toStdString(); + } + qt_config->endArray(); + size = qt_config->beginReadArray(QStringLiteral("ip_ban_list")); + UISettings::values.multiplayer_ban_list.second.resize(size); + for (int i = 0; i < size; ++i) { + qt_config->setArrayIndex(i); + UISettings::values.multiplayer_ban_list.second[i] = + ReadSetting(QStringLiteral("ip")).toString().toStdString(); + } + qt_config->endArray(); + + qt_config->endGroup(); +} + void Config::ReadValues() { if (global) { ReadControlValues(); @@ -920,6 +914,7 @@ void Config::ReadValues() { ReadRendererValues(); ReadAudioValues(); ReadSystemValues(); + ReadMultiplayerValues(); } void Config::SavePlayerValue(std::size_t player_index) { @@ -1069,6 +1064,7 @@ void Config::SaveValues() { SaveRendererValues(); SaveAudioValues(); SaveSystemValues(); + SaveMultiplayerValues(); } void Config::SaveAudioValues() { @@ -1205,40 +1201,6 @@ void Config::SaveMiscellaneousValues() { qt_config->endGroup(); } -void Config::SaveMultiplayerValues() { - qt_config->beginGroup(QStringLiteral("Multiplayer")); - - WriteSetting(QStringLiteral("nickname"), UISettings::values.nickname, QString{}); - WriteSetting(QStringLiteral("ip"), UISettings::values.ip, QString{}); - WriteSetting(QStringLiteral("port"), UISettings::values.port, Network::DefaultRoomPort); - WriteSetting(QStringLiteral("room_nickname"), UISettings::values.room_nickname, QString{}); - WriteSetting(QStringLiteral("room_name"), UISettings::values.room_name, QString{}); - WriteSetting(QStringLiteral("room_port"), UISettings::values.room_port, - QStringLiteral("24872")); - WriteSetting(QStringLiteral("host_type"), UISettings::values.host_type, 0); - WriteSetting(QStringLiteral("max_player"), UISettings::values.max_player, 8); - WriteSetting(QStringLiteral("game_id"), UISettings::values.game_id, 0); - WriteSetting(QStringLiteral("room_description"), UISettings::values.room_description, - QString{}); - // Write ban list - qt_config->beginWriteArray(QStringLiteral("username_ban_list")); - for (std::size_t i = 0; i < UISettings::values.ban_list.first.size(); ++i) { - qt_config->setArrayIndex(static_cast(i)); - WriteSetting(QStringLiteral("username"), - QString::fromStdString(UISettings::values.ban_list.first[i])); - } - qt_config->endArray(); - qt_config->beginWriteArray(QStringLiteral("ip_ban_list")); - for (std::size_t i = 0; i < UISettings::values.ban_list.second.size(); ++i) { - qt_config->setArrayIndex(static_cast(i)); - WriteSetting(QStringLiteral("ip"), - QString::fromStdString(UISettings::values.ban_list.second[i])); - } - qt_config->endArray(); - - qt_config->endGroup(); -} - void Config::SavePathValues() { qt_config->beginGroup(QStringLiteral("Paths")); @@ -1490,6 +1452,40 @@ void Config::SaveWebServiceValues() { qt_config->endGroup(); } +void Config::SaveMultiplayerValues() { + qt_config->beginGroup(QStringLiteral("Multiplayer")); + + WriteBasicSetting(UISettings::values.multiplayer_nickname); + WriteBasicSetting(UISettings::values.multiplayer_ip); + WriteBasicSetting(UISettings::values.multiplayer_port); + WriteBasicSetting(UISettings::values.multiplayer_room_nickname); + WriteBasicSetting(UISettings::values.multiplayer_room_name); + WriteBasicSetting(UISettings::values.multiplayer_room_port); + WriteBasicSetting(UISettings::values.multiplayer_host_type); + WriteBasicSetting(UISettings::values.multiplayer_port); + WriteBasicSetting(UISettings::values.multiplayer_max_player); + WriteBasicSetting(UISettings::values.multiplayer_game_id); + WriteBasicSetting(UISettings::values.multiplayer_room_description); + + // Write ban list + qt_config->beginWriteArray(QStringLiteral("username_ban_list")); + for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.first.size(); ++i) { + qt_config->setArrayIndex(static_cast(i)); + WriteSetting(QStringLiteral("username"), + QString::fromStdString(UISettings::values.multiplayer_ban_list.first[i])); + } + qt_config->endArray(); + qt_config->beginWriteArray(QStringLiteral("ip_ban_list")); + for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.second.size(); ++i) { + qt_config->setArrayIndex(static_cast(i)); + WriteSetting(QStringLiteral("ip"), + QString::fromStdString(UISettings::values.multiplayer_ban_list.second[i])); + } + qt_config->endArray(); + + qt_config->endGroup(); +} + QVariant Config::ReadSetting(const QString& name) const { return qt_config->value(name); } diff --git a/src/yuzu/multiplayer/chat_room.cpp b/src/yuzu/multiplayer/chat_room.cpp index 6dd4bc36d..7048ee1fc 100644 --- a/src/yuzu/multiplayer/chat_room.cpp +++ b/src/yuzu/multiplayer/chat_room.cpp @@ -390,7 +390,7 @@ void ChatRoom::SetPlayerList(const Network::RoomMember::MemberList& member_list) return; QPixmap pixmap; if (!pixmap.loadFromData(reinterpret_cast(result.data()), - result.size())) + static_cast(result.size()))) return; icon_cache[avatar_url] = pixmap.scaled(48, 48, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); diff --git a/src/yuzu/multiplayer/direct_connect.cpp b/src/yuzu/multiplayer/direct_connect.cpp index 27741d657..837baf85c 100644 --- a/src/yuzu/multiplayer/direct_connect.cpp +++ b/src/yuzu/multiplayer/direct_connect.cpp @@ -32,15 +32,15 @@ DirectConnectWindow::DirectConnectWindow(QWidget* parent) connect(watcher, &QFutureWatcher::finished, this, &DirectConnectWindow::OnConnection); ui->nickname->setValidator(validation.GetNickname()); - ui->nickname->setText(UISettings::values.nickname); + ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue()); if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) { // Use yuzu Web Service user name as nickname by default ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); } ui->ip->setValidator(validation.GetIP()); - ui->ip->setText(UISettings::values.ip); + ui->ip->setText(UISettings::values.multiplayer_ip.GetValue()); ui->port->setValidator(validation.GetPort()); - ui->port->setText(UISettings::values.port); + ui->port->setText(QString::number(UISettings::values.multiplayer_port.GetValue())); // TODO(jroweboy): Show or hide the connection options based on the current value of the combo // box. Add this back in when the traversal server support is added. @@ -86,16 +86,18 @@ void DirectConnectWindow::Connect() { } // Store settings - UISettings::values.nickname = ui->nickname->text(); - UISettings::values.ip = ui->ip->text(); - UISettings::values.port = (ui->port->isModified() && !ui->port->text().isEmpty()) - ? ui->port->text() - : UISettings::values.port; + UISettings::values.multiplayer_nickname = ui->nickname->text(); + UISettings::values.multiplayer_ip = ui->ip->text(); + if (ui->port->isModified() && !ui->port->text().isEmpty()) { + UISettings::values.multiplayer_port = ui->port->text().toInt(); + } else { + UISettings::values.multiplayer_port = UISettings::values.multiplayer_port.GetDefault(); + } // attempt to connect in a different thread QFuture f = QtConcurrent::run([&] { if (auto room_member = Network::GetRoomMember().lock()) { - auto port = UISettings::values.port.toUInt(); + auto port = UISettings::values.multiplayer_port.GetValue(); room_member->Join(ui->nickname->text().toStdString(), "", ui->ip->text().toStdString().c_str(), port, 0, Network::NoPreferredMac, ui->password->text().toStdString().c_str()); diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp index 1b73e2bec..5470b8b86 100644 --- a/src/yuzu/multiplayer/host_room.cpp +++ b/src/yuzu/multiplayer/host_room.cpp @@ -51,23 +51,24 @@ HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list, connect(ui->host, &QPushButton::clicked, this, &HostRoomWindow::Host); // Restore the settings: - ui->username->setText(UISettings::values.room_nickname); + ui->username->setText(UISettings::values.multiplayer_room_nickname.GetValue()); if (ui->username->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) { // Use yuzu Web Service user name as nickname by default ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); } - ui->room_name->setText(UISettings::values.room_name); - ui->port->setText(UISettings::values.room_port); - ui->max_player->setValue(UISettings::values.max_player); - int index = UISettings::values.host_type; + ui->room_name->setText(UISettings::values.multiplayer_room_name.GetValue()); + ui->port->setText(QString::number(UISettings::values.multiplayer_room_port.GetValue())); + ui->max_player->setValue(UISettings::values.multiplayer_max_player.GetValue()); + int index = UISettings::values.multiplayer_host_type.GetValue(); if (index < ui->host_type->count()) { ui->host_type->setCurrentIndex(index); } - index = ui->game_list->findData(UISettings::values.game_id, GameListItemPath::ProgramIdRole); + index = ui->game_list->findData(UISettings::values.multiplayer_game_id.GetValue(), + GameListItemPath::ProgramIdRole); if (index != -1) { ui->game_list->setCurrentIndex(index); } - ui->room_description->setText(UISettings::values.room_description); + ui->room_description->setText(UISettings::values.multiplayer_room_description.GetValue()); } HostRoomWindow::~HostRoomWindow() = default; @@ -91,7 +92,8 @@ std::unique_ptr HostRoomWindow::CreateVerifyBacken std::unique_ptr verify_backend; if (use_validation) { #ifdef ENABLE_WEB_SERVICE - verify_backend = std::make_unique(Settings::values.web_api_url); + verify_backend = + std::make_unique(Settings::values.web_api_url.GetValue()); #else verify_backend = std::make_unique(); #endif @@ -137,7 +139,7 @@ void HostRoomWindow::Host() { const bool is_public = ui->host_type->currentIndex() == 0; Network::Room::BanList ban_list{}; if (ui->load_ban_list->isChecked()) { - ban_list = UISettings::values.ban_list; + ban_list = UISettings::values.multiplayer_ban_list; } if (auto room = Network::GetRoom().lock()) { bool created = room->Create( @@ -181,8 +183,9 @@ void HostRoomWindow::Host() { std::string token; #ifdef ENABLE_WEB_SERVICE if (is_public) { - WebService::Client client(Settings::values.web_api_url, Settings::values.yuzu_username, - Settings::values.yuzu_token); + WebService::Client client(Settings::values.web_api_url.GetValue(), + Settings::values.yuzu_username.GetValue(), + Settings::values.yuzu_token.GetValue()); if (auto room = Network::GetRoom().lock()) { token = client.GetExternalJWT(room->GetVerifyUID()).returned_data; } @@ -198,17 +201,19 @@ void HostRoomWindow::Host() { Network::NoPreferredMac, password, token); // Store settings - UISettings::values.room_nickname = ui->username->text(); - UISettings::values.room_name = ui->room_name->text(); - UISettings::values.game_id = + UISettings::values.multiplayer_room_nickname = ui->username->text(); + UISettings::values.multiplayer_room_name = ui->room_name->text(); + UISettings::values.multiplayer_game_id = ui->game_list->currentData(GameListItemPath::ProgramIdRole).toLongLong(); - UISettings::values.max_player = ui->max_player->value(); + UISettings::values.multiplayer_max_player = ui->max_player->value(); - UISettings::values.host_type = ui->host_type->currentIndex(); - 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(); + UISettings::values.multiplayer_host_type = ui->host_type->currentIndex(); + if (ui->port->isModified() && !ui->port->text().isEmpty()) { + UISettings::values.multiplayer_room_port = ui->port->text().toInt(); + } else { + UISettings::values.multiplayer_room_port = Network::DefaultRoomPort; + } + UISettings::values.multiplayer_room_description = ui->room_description->toPlainText(); ui->host->setEnabled(true); close(); } diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp index fcaa7b517..364b4605e 100644 --- a/src/yuzu/multiplayer/lobby.cpp +++ b/src/yuzu/multiplayer/lobby.cpp @@ -56,7 +56,7 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu); ui->nickname->setValidator(validation.GetNickname()); - ui->nickname->setText(UISettings::values.nickname); + ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue()); if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) { // Use yuzu Web Service user name as nickname by default ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); @@ -154,9 +154,11 @@ void Lobby::OnJoinRoom(const QModelIndex& source) { QFuture f = QtConcurrent::run([nickname, ip, port, password, verify_UID] { std::string token; #ifdef ENABLE_WEB_SERVICE - if (!Settings::values.yuzu_username.empty() && !Settings::values.yuzu_token.empty()) { - WebService::Client client(Settings::values.web_api_url, Settings::values.yuzu_username, - Settings::values.yuzu_token); + if (!Settings::values.yuzu_username.GetValue().empty() && + !Settings::values.yuzu_token.GetValue().empty()) { + WebService::Client client(Settings::values.web_api_url.GetValue(), + Settings::values.yuzu_username.GetValue(), + Settings::values.yuzu_token.GetValue()); token = client.GetExternalJWT(verify_UID).returned_data; if (token.empty()) { LOG_ERROR(WebService, "Could not get external JWT, verification may fail"); @@ -175,9 +177,11 @@ void Lobby::OnJoinRoom(const QModelIndex& source) { // TODO(jroweboy): disable widgets and display a connecting while we wait // Save settings - UISettings::values.nickname = ui->nickname->text(); - UISettings::values.ip = proxy->data(connection_index, LobbyItemHost::HostIPRole).toString(); - UISettings::values.port = proxy->data(connection_index, LobbyItemHost::HostPortRole).toString(); + UISettings::values.multiplayer_nickname = ui->nickname->text(); + UISettings::values.multiplayer_ip = + proxy->data(connection_index, LobbyItemHost::HostIPRole).toString(); + UISettings::values.multiplayer_port = + proxy->data(connection_index, LobbyItemHost::HostPortRole).toInt(); } void Lobby::ResetModel() { diff --git a/src/yuzu/multiplayer/state.cpp b/src/yuzu/multiplayer/state.cpp index e96b03e5d..ee138739b 100644 --- a/src/yuzu/multiplayer/state.cpp +++ b/src/yuzu/multiplayer/state.cpp @@ -232,7 +232,7 @@ bool MultiplayerState::OnCloseRoom() { return true; } // Save ban list - UISettings::values.ban_list = std::move(room->GetBanList()); + UISettings::values.multiplayer_ban_list = std::move(room->GetBanList()); room->Destroy(); announce_multiplayer_session->Stop(); diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index aca1a28e1..83a6cffa3 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -103,17 +103,17 @@ struct Values { Settings::Setting callout_flags{0, "calloutFlags"}; // multiplayer settings - QString nickname; - QString ip; - QString port; - QString room_nickname; - QString room_name; - quint32 max_player; - QString room_port; - uint host_type; - qulonglong game_id; - QString room_description; - std::pair, std::vector> ban_list; + Settings::Setting multiplayer_nickname{QStringLiteral("yuzu"), "nickname"}; + Settings::Setting multiplayer_ip{{}, "ip"}; + Settings::SwitchableSetting multiplayer_port{24872, 0, 65535, "port"}; + Settings::Setting multiplayer_room_nickname{{}, "room_nickname"}; + Settings::Setting multiplayer_room_name{{}, "room_name"}; + Settings::SwitchableSetting multiplayer_max_player{8, 0, 8, "max_player"}; + Settings::SwitchableSetting multiplayer_room_port{24872, 0, 65535, "room_port"}; + Settings::SwitchableSetting multiplayer_host_type{0, 0, 1, "host_type"}; + Settings::Setting multiplayer_game_id{{}, "game_id"}; + Settings::Setting multiplayer_room_description{{}, "room_description"}; + std::pair, std::vector> multiplayer_ban_list; // logging Settings::Setting show_console{false, "showConsole"};