summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar FearlessTobi2022-07-15 19:45:35 +0200
committerGravatar FearlessTobi2022-07-25 21:59:30 +0200
commit6c8e45618578de1406c0bf4a7f976bd4903c339c (patch)
tree25b959db6f30fe75bf5c6fa667ed92af71117986
parentFix compilation on linux gcc (diff)
downloadyuzu-6c8e45618578de1406c0bf4a7f976bd4903c339c.tar.gz
yuzu-6c8e45618578de1406c0bf4a7f976bd4903c339c.tar.xz
yuzu-6c8e45618578de1406c0bf4a7f976bd4903c339c.zip
Address first part of review comments
Diffstat (limited to '')
-rw-r--r--.gitmodules3
-rw-r--r--externals/CMakeLists.txt5
-rw-r--r--src/core/CMakeLists.txt10
-rw-r--r--src/input_common/helpers/udp_protocol.h2
-rw-r--r--src/network/room.h2
-rw-r--r--src/web_service/CMakeLists.txt4
-rw-r--r--src/web_service/verify_user_jwt.cpp60
-rw-r--r--src/web_service/verify_user_jwt.h25
-rw-r--r--src/yuzu/CMakeLists.txt4
-rw-r--r--src/yuzu/configuration/config.cpp148
-rw-r--r--src/yuzu/multiplayer/chat_room.cpp2
-rw-r--r--src/yuzu/multiplayer/direct_connect.cpp20
-rw-r--r--src/yuzu/multiplayer/host_room.cpp45
-rw-r--r--src/yuzu/multiplayer/lobby.cpp18
-rw-r--r--src/yuzu/multiplayer/state.cpp2
-rw-r--r--src/yuzu/uisettings.h22
16 files changed, 239 insertions, 133 deletions
diff --git a/.gitmodules b/.gitmodules
index d8e04923a..26c6735cd 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -46,3 +46,6 @@
46[submodule "vcpkg"] 46[submodule "vcpkg"]
47 path = externals/vcpkg 47 path = externals/vcpkg
48 url = https://github.com/Microsoft/vcpkg.git 48 url = https://github.com/Microsoft/vcpkg.git
49[submodule "cpp-jwt"]
50 path = externals/cpp-jwt
51 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)
116 if (WIN32) 116 if (WIN32)
117 target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32) 117 target_link_libraries(httplib INTERFACE crypt32 cryptui ws2_32)
118 endif() 118 endif()
119
120 # cpp-jwt
121 add_library(cpp-jwt INTERFACE)
122 target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
123 target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
119endif() 124endif()
120 125
121# Opus 126# 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
716 hle/service/vi/vi_u.h 716 hle/service/vi/vi_u.h
717 hle/service/wlan/wlan.cpp 717 hle/service/wlan/wlan.cpp
718 hle/service/wlan/wlan.h 718 hle/service/wlan/wlan.h
719 internal_network/network.cpp
720 internal_network/network.h
721 internal_network/network_interface.cpp
722 internal_network/network_interface.h
723 internal_network/sockets.h
719 loader/deconstructed_rom_directory.cpp 724 loader/deconstructed_rom_directory.cpp
720 loader/deconstructed_rom_directory.h 725 loader/deconstructed_rom_directory.h
721 loader/elf.cpp 726 loader/elf.cpp
@@ -743,11 +748,6 @@ add_library(core STATIC
743 memory/dmnt_cheat_vm.h 748 memory/dmnt_cheat_vm.h
744 memory.cpp 749 memory.cpp
745 memory.h 750 memory.h
746 internal_network/network.cpp
747 internal_network/network.h
748 internal_network/network_interface.cpp
749 internal_network/network_interface.h
750 internal_network/sockets.h
751 perf_stats.cpp 751 perf_stats.cpp
752 perf_stats.h 752 perf_stats.h
753 reporter.cpp 753 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 {
85struct Version {}; 85struct Version {};
86/** 86/**
87 * Requests the server to send information about what controllers are plugged into the ports 87 * Requests the server to send information about what controllers are plugged into the ports
88 * In citra's case, we only have one controller, so for simplicity's sake, we can just send a 88 * In yuzu's case, we only have one controller, so for simplicity's sake, we can just send a
89 * request explicitly for the first controller port and leave it at that. In the future it would be 89 * request explicitly for the first controller port and leave it at that. In the future it would be
90 * nice to make this configurable 90 * nice to make this configurable
91 */ 91 */
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 @@
13 13
14namespace Network { 14namespace Network {
15 15
16constexpr u32 network_version = 4; ///< The version of this Room and RoomMember 16constexpr u32 network_version = 1; ///< The version of this Room and RoomMember
17 17
18constexpr u16 DefaultRoomPort = 24872; 18constexpr u16 DefaultRoomPort = 24872;
19 19
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
5 telemetry_json.h 5 telemetry_json.h
6 verify_login.cpp 6 verify_login.cpp
7 verify_login.h 7 verify_login.h
8 verify_user_jwt.cpp
9 verify_user_jwt.h
8 web_backend.cpp 10 web_backend.cpp
9 web_backend.h 11 web_backend.h
10 web_result.h 12 web_result.h
11) 13)
12 14
13create_target_directory_groups(web_service) 15create_target_directory_groups(web_service)
14target_link_libraries(web_service PRIVATE common network nlohmann_json::nlohmann_json httplib) 16target_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 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <system_error>
6#include <jwt/jwt.hpp>
7#include "common/logging/log.h"
8#include "web_service/verify_user_jwt.h"
9#include "web_service/web_backend.h"
10#include "web_service/web_result.h"
11
12namespace WebService {
13
14static std::string public_key;
15std::string GetPublicKey(const std::string& host) {
16 if (public_key.empty()) {
17 Client client(host, "", ""); // no need for credentials here
18 public_key = client.GetPlain("/jwt/external/key.pem", true).returned_data;
19 if (public_key.empty()) {
20 LOG_ERROR(WebService, "Could not fetch external JWT public key, verification may fail");
21 } else {
22 LOG_INFO(WebService, "Fetched external JWT public key (size={})", public_key.size());
23 }
24 }
25 return public_key;
26}
27
28VerifyUserJWT::VerifyUserJWT(const std::string& host) : pub_key(GetPublicKey(host)) {}
29
30Network::VerifyUser::UserData VerifyUserJWT::LoadUserData(const std::string& verify_UID,
31 const std::string& token) {
32 const std::string audience = fmt::format("external-{}", verify_UID);
33 using namespace jwt::params;
34 std::error_code error;
35 auto decoded =
36 jwt::decode(token, algorithms({"rs256"}), error, secret(pub_key), issuer("yuzu-core"),
37 aud(audience), validate_iat(true), validate_jti(true));
38 if (error) {
39 LOG_INFO(WebService, "Verification failed: category={}, code={}, message={}",
40 error.category().name(), error.value(), error.message());
41 return {};
42 }
43 Network::VerifyUser::UserData user_data{};
44 if (decoded.payload().has_claim("username")) {
45 user_data.username = decoded.payload().get_claim_value<std::string>("username");
46 }
47 if (decoded.payload().has_claim("displayName")) {
48 user_data.display_name = decoded.payload().get_claim_value<std::string>("displayName");
49 }
50 if (decoded.payload().has_claim("avatarUrl")) {
51 user_data.avatar_url = decoded.payload().get_claim_value<std::string>("avatarUrl");
52 }
53 if (decoded.payload().has_claim("roles")) {
54 auto roles = decoded.payload().get_claim_value<std::vector<std::string>>("roles");
55 user_data.moderator = std::find(roles.begin(), roles.end(), "moderator") != roles.end();
56 }
57 return user_data;
58}
59
60} // 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 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <fmt/format.h>
8#include "network/verify_user.h"
9#include "web_service/web_backend.h"
10
11namespace WebService {
12
13class VerifyUserJWT final : public Network::VerifyUser::Backend {
14public:
15 VerifyUserJWT(const std::string& host);
16 ~VerifyUserJWT() = default;
17
18 Network::VerifyUser::UserData LoadUserData(const std::string& verify_UID,
19 const std::string& token) override;
20
21private:
22 std::string pub_key;
23};
24
25} // 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)
326 target_compile_definitions(yuzu PRIVATE -DUSE_DISCORD_PRESENCE) 326 target_compile_definitions(yuzu PRIVATE -DUSE_DISCORD_PRESENCE)
327endif() 327endif()
328 328
329if (ENABLE_WEB_SERVICE)
330 target_compile_definitions(yuzu PRIVATE -DENABLE_WEB_SERVICE)
331endif()
332
329if (YUZU_USE_QT_WEB_ENGINE) 333if (YUZU_USE_QT_WEB_ENGINE)
330 target_link_libraries(yuzu PRIVATE Qt::WebEngineCore Qt::WebEngineWidgets) 334 target_link_libraries(yuzu PRIVATE Qt::WebEngineCore Qt::WebEngineWidgets)
331 target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_WEB_ENGINE) 335 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() {
585 qt_config->endGroup(); 585 qt_config->endGroup();
586} 586}
587 587
588void Config::ReadMultiplayerValues() {
589 qt_config->beginGroup(QStringLiteral("Multiplayer"));
590
591 UISettings::values.nickname = ReadSetting(QStringLiteral("nickname"), QString{}).toString();
592 UISettings::values.ip = ReadSetting(QStringLiteral("ip"), QString{}).toString();
593 UISettings::values.port =
594 ReadSetting(QStringLiteral("port"), Network::DefaultRoomPort).toString();
595 UISettings::values.room_nickname =
596 ReadSetting(QStringLiteral("room_nickname"), QString{}).toString();
597 UISettings::values.room_name = ReadSetting(QStringLiteral("room_name"), QString{}).toString();
598 UISettings::values.room_port =
599 ReadSetting(QStringLiteral("room_port"), QStringLiteral("24872")).toString();
600 bool ok;
601 UISettings::values.host_type = ReadSetting(QStringLiteral("host_type"), 0).toUInt(&ok);
602 if (!ok) {
603 UISettings::values.host_type = 0;
604 }
605 UISettings::values.max_player = ReadSetting(QStringLiteral("max_player"), 8).toUInt();
606 UISettings::values.game_id = ReadSetting(QStringLiteral("game_id"), 0).toULongLong();
607 UISettings::values.room_description =
608 ReadSetting(QStringLiteral("room_description"), QString{}).toString();
609 // Read ban list back
610 int size = qt_config->beginReadArray(QStringLiteral("username_ban_list"));
611 UISettings::values.ban_list.first.resize(size);
612 for (int i = 0; i < size; ++i) {
613 qt_config->setArrayIndex(i);
614 UISettings::values.ban_list.first[i] =
615 ReadSetting(QStringLiteral("username")).toString().toStdString();
616 }
617 qt_config->endArray();
618 size = qt_config->beginReadArray(QStringLiteral("ip_ban_list"));
619 UISettings::values.ban_list.second.resize(size);
620 for (int i = 0; i < size; ++i) {
621 qt_config->setArrayIndex(i);
622 UISettings::values.ban_list.second[i] =
623 ReadSetting(QStringLiteral("ip")).toString().toStdString();
624 }
625 qt_config->endArray();
626
627 qt_config->endGroup();
628}
629
630void Config::ReadPathValues() { 588void Config::ReadPathValues() {
631 qt_config->beginGroup(QStringLiteral("Paths")); 589 qt_config->beginGroup(QStringLiteral("Paths"));
632 590
@@ -904,6 +862,42 @@ void Config::ReadWebServiceValues() {
904 qt_config->endGroup(); 862 qt_config->endGroup();
905} 863}
906 864
865void Config::ReadMultiplayerValues() {
866 qt_config->beginGroup(QStringLiteral("Multiplayer"));
867
868 ReadBasicSetting(UISettings::values.multiplayer_nickname);
869 ReadBasicSetting(UISettings::values.multiplayer_ip);
870 ReadBasicSetting(UISettings::values.multiplayer_port);
871 ReadBasicSetting(UISettings::values.multiplayer_room_nickname);
872 ReadBasicSetting(UISettings::values.multiplayer_room_name);
873 ReadBasicSetting(UISettings::values.multiplayer_room_port);
874 ReadBasicSetting(UISettings::values.multiplayer_host_type);
875 ReadBasicSetting(UISettings::values.multiplayer_port);
876 ReadBasicSetting(UISettings::values.multiplayer_max_player);
877 ReadBasicSetting(UISettings::values.multiplayer_game_id);
878 ReadBasicSetting(UISettings::values.multiplayer_room_description);
879
880 // Read ban list back
881 int size = qt_config->beginReadArray(QStringLiteral("username_ban_list"));
882 UISettings::values.multiplayer_ban_list.first.resize(size);
883 for (int i = 0; i < size; ++i) {
884 qt_config->setArrayIndex(i);
885 UISettings::values.multiplayer_ban_list.first[i] =
886 ReadSetting(QStringLiteral("username")).toString().toStdString();
887 }
888 qt_config->endArray();
889 size = qt_config->beginReadArray(QStringLiteral("ip_ban_list"));
890 UISettings::values.multiplayer_ban_list.second.resize(size);
891 for (int i = 0; i < size; ++i) {
892 qt_config->setArrayIndex(i);
893 UISettings::values.multiplayer_ban_list.second[i] =
894 ReadSetting(QStringLiteral("ip")).toString().toStdString();
895 }
896 qt_config->endArray();
897
898 qt_config->endGroup();
899}
900
907void Config::ReadValues() { 901void Config::ReadValues() {
908 if (global) { 902 if (global) {
909 ReadControlValues(); 903 ReadControlValues();
@@ -920,6 +914,7 @@ void Config::ReadValues() {
920 ReadRendererValues(); 914 ReadRendererValues();
921 ReadAudioValues(); 915 ReadAudioValues();
922 ReadSystemValues(); 916 ReadSystemValues();
917 ReadMultiplayerValues();
923} 918}
924 919
925void Config::SavePlayerValue(std::size_t player_index) { 920void Config::SavePlayerValue(std::size_t player_index) {
@@ -1069,6 +1064,7 @@ void Config::SaveValues() {
1069 SaveRendererValues(); 1064 SaveRendererValues();
1070 SaveAudioValues(); 1065 SaveAudioValues();
1071 SaveSystemValues(); 1066 SaveSystemValues();
1067 SaveMultiplayerValues();
1072} 1068}
1073 1069
1074void Config::SaveAudioValues() { 1070void Config::SaveAudioValues() {
@@ -1205,40 +1201,6 @@ void Config::SaveMiscellaneousValues() {
1205 qt_config->endGroup(); 1201 qt_config->endGroup();
1206} 1202}
1207 1203
1208void Config::SaveMultiplayerValues() {
1209 qt_config->beginGroup(QStringLiteral("Multiplayer"));
1210
1211 WriteSetting(QStringLiteral("nickname"), UISettings::values.nickname, QString{});
1212 WriteSetting(QStringLiteral("ip"), UISettings::values.ip, QString{});
1213 WriteSetting(QStringLiteral("port"), UISettings::values.port, Network::DefaultRoomPort);
1214 WriteSetting(QStringLiteral("room_nickname"), UISettings::values.room_nickname, QString{});
1215 WriteSetting(QStringLiteral("room_name"), UISettings::values.room_name, QString{});
1216 WriteSetting(QStringLiteral("room_port"), UISettings::values.room_port,
1217 QStringLiteral("24872"));
1218 WriteSetting(QStringLiteral("host_type"), UISettings::values.host_type, 0);
1219 WriteSetting(QStringLiteral("max_player"), UISettings::values.max_player, 8);
1220 WriteSetting(QStringLiteral("game_id"), UISettings::values.game_id, 0);
1221 WriteSetting(QStringLiteral("room_description"), UISettings::values.room_description,
1222 QString{});
1223 // Write ban list
1224 qt_config->beginWriteArray(QStringLiteral("username_ban_list"));
1225 for (std::size_t i = 0; i < UISettings::values.ban_list.first.size(); ++i) {
1226 qt_config->setArrayIndex(static_cast<int>(i));
1227 WriteSetting(QStringLiteral("username"),
1228 QString::fromStdString(UISettings::values.ban_list.first[i]));
1229 }
1230 qt_config->endArray();
1231 qt_config->beginWriteArray(QStringLiteral("ip_ban_list"));
1232 for (std::size_t i = 0; i < UISettings::values.ban_list.second.size(); ++i) {
1233 qt_config->setArrayIndex(static_cast<int>(i));
1234 WriteSetting(QStringLiteral("ip"),
1235 QString::fromStdString(UISettings::values.ban_list.second[i]));
1236 }
1237 qt_config->endArray();
1238
1239 qt_config->endGroup();
1240}
1241
1242void Config::SavePathValues() { 1204void Config::SavePathValues() {
1243 qt_config->beginGroup(QStringLiteral("Paths")); 1205 qt_config->beginGroup(QStringLiteral("Paths"));
1244 1206
@@ -1490,6 +1452,40 @@ void Config::SaveWebServiceValues() {
1490 qt_config->endGroup(); 1452 qt_config->endGroup();
1491} 1453}
1492 1454
1455void Config::SaveMultiplayerValues() {
1456 qt_config->beginGroup(QStringLiteral("Multiplayer"));
1457
1458 WriteBasicSetting(UISettings::values.multiplayer_nickname);
1459 WriteBasicSetting(UISettings::values.multiplayer_ip);
1460 WriteBasicSetting(UISettings::values.multiplayer_port);
1461 WriteBasicSetting(UISettings::values.multiplayer_room_nickname);
1462 WriteBasicSetting(UISettings::values.multiplayer_room_name);
1463 WriteBasicSetting(UISettings::values.multiplayer_room_port);
1464 WriteBasicSetting(UISettings::values.multiplayer_host_type);
1465 WriteBasicSetting(UISettings::values.multiplayer_port);
1466 WriteBasicSetting(UISettings::values.multiplayer_max_player);
1467 WriteBasicSetting(UISettings::values.multiplayer_game_id);
1468 WriteBasicSetting(UISettings::values.multiplayer_room_description);
1469
1470 // Write ban list
1471 qt_config->beginWriteArray(QStringLiteral("username_ban_list"));
1472 for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.first.size(); ++i) {
1473 qt_config->setArrayIndex(static_cast<int>(i));
1474 WriteSetting(QStringLiteral("username"),
1475 QString::fromStdString(UISettings::values.multiplayer_ban_list.first[i]));
1476 }
1477 qt_config->endArray();
1478 qt_config->beginWriteArray(QStringLiteral("ip_ban_list"));
1479 for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.second.size(); ++i) {
1480 qt_config->setArrayIndex(static_cast<int>(i));
1481 WriteSetting(QStringLiteral("ip"),
1482 QString::fromStdString(UISettings::values.multiplayer_ban_list.second[i]));
1483 }
1484 qt_config->endArray();
1485
1486 qt_config->endGroup();
1487}
1488
1493QVariant Config::ReadSetting(const QString& name) const { 1489QVariant Config::ReadSetting(const QString& name) const {
1494 return qt_config->value(name); 1490 return qt_config->value(name);
1495} 1491}
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)
390 return; 390 return;
391 QPixmap pixmap; 391 QPixmap pixmap;
392 if (!pixmap.loadFromData(reinterpret_cast<const u8*>(result.data()), 392 if (!pixmap.loadFromData(reinterpret_cast<const u8*>(result.data()),
393 result.size())) 393 static_cast<uint>(result.size())))
394 return; 394 return;
395 icon_cache[avatar_url] = 395 icon_cache[avatar_url] =
396 pixmap.scaled(48, 48, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 396 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)
32 connect(watcher, &QFutureWatcher<void>::finished, this, &DirectConnectWindow::OnConnection); 32 connect(watcher, &QFutureWatcher<void>::finished, this, &DirectConnectWindow::OnConnection);
33 33
34 ui->nickname->setValidator(validation.GetNickname()); 34 ui->nickname->setValidator(validation.GetNickname());
35 ui->nickname->setText(UISettings::values.nickname); 35 ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue());
36 if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) { 36 if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
37 // Use yuzu Web Service user name as nickname by default 37 // Use yuzu Web Service user name as nickname by default
38 ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); 38 ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
39 } 39 }
40 ui->ip->setValidator(validation.GetIP()); 40 ui->ip->setValidator(validation.GetIP());
41 ui->ip->setText(UISettings::values.ip); 41 ui->ip->setText(UISettings::values.multiplayer_ip.GetValue());
42 ui->port->setValidator(validation.GetPort()); 42 ui->port->setValidator(validation.GetPort());
43 ui->port->setText(UISettings::values.port); 43 ui->port->setText(QString::number(UISettings::values.multiplayer_port.GetValue()));
44 44
45 // TODO(jroweboy): Show or hide the connection options based on the current value of the combo 45 // TODO(jroweboy): Show or hide the connection options based on the current value of the combo
46 // box. Add this back in when the traversal server support is added. 46 // box. Add this back in when the traversal server support is added.
@@ -86,16 +86,18 @@ void DirectConnectWindow::Connect() {
86 } 86 }
87 87
88 // Store settings 88 // Store settings
89 UISettings::values.nickname = ui->nickname->text(); 89 UISettings::values.multiplayer_nickname = ui->nickname->text();
90 UISettings::values.ip = ui->ip->text(); 90 UISettings::values.multiplayer_ip = ui->ip->text();
91 UISettings::values.port = (ui->port->isModified() && !ui->port->text().isEmpty()) 91 if (ui->port->isModified() && !ui->port->text().isEmpty()) {
92 ? ui->port->text() 92 UISettings::values.multiplayer_port = ui->port->text().toInt();
93 : UISettings::values.port; 93 } else {
94 UISettings::values.multiplayer_port = UISettings::values.multiplayer_port.GetDefault();
95 }
94 96
95 // attempt to connect in a different thread 97 // attempt to connect in a different thread
96 QFuture<void> f = QtConcurrent::run([&] { 98 QFuture<void> f = QtConcurrent::run([&] {
97 if (auto room_member = Network::GetRoomMember().lock()) { 99 if (auto room_member = Network::GetRoomMember().lock()) {
98 auto port = UISettings::values.port.toUInt(); 100 auto port = UISettings::values.multiplayer_port.GetValue();
99 room_member->Join(ui->nickname->text().toStdString(), "", 101 room_member->Join(ui->nickname->text().toStdString(), "",
100 ui->ip->text().toStdString().c_str(), port, 0, 102 ui->ip->text().toStdString().c_str(), port, 0,
101 Network::NoPreferredMac, ui->password->text().toStdString().c_str()); 103 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,
51 connect(ui->host, &QPushButton::clicked, this, &HostRoomWindow::Host); 51 connect(ui->host, &QPushButton::clicked, this, &HostRoomWindow::Host);
52 52
53 // Restore the settings: 53 // Restore the settings:
54 ui->username->setText(UISettings::values.room_nickname); 54 ui->username->setText(UISettings::values.multiplayer_room_nickname.GetValue());
55 if (ui->username->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) { 55 if (ui->username->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
56 // Use yuzu Web Service user name as nickname by default 56 // Use yuzu Web Service user name as nickname by default
57 ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); 57 ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
58 } 58 }
59 ui->room_name->setText(UISettings::values.room_name); 59 ui->room_name->setText(UISettings::values.multiplayer_room_name.GetValue());
60 ui->port->setText(UISettings::values.room_port); 60 ui->port->setText(QString::number(UISettings::values.multiplayer_room_port.GetValue()));
61 ui->max_player->setValue(UISettings::values.max_player); 61 ui->max_player->setValue(UISettings::values.multiplayer_max_player.GetValue());
62 int index = UISettings::values.host_type; 62 int index = UISettings::values.multiplayer_host_type.GetValue();
63 if (index < ui->host_type->count()) { 63 if (index < ui->host_type->count()) {
64 ui->host_type->setCurrentIndex(index); 64 ui->host_type->setCurrentIndex(index);
65 } 65 }
66 index = ui->game_list->findData(UISettings::values.game_id, GameListItemPath::ProgramIdRole); 66 index = ui->game_list->findData(UISettings::values.multiplayer_game_id.GetValue(),
67 GameListItemPath::ProgramIdRole);
67 if (index != -1) { 68 if (index != -1) {
68 ui->game_list->setCurrentIndex(index); 69 ui->game_list->setCurrentIndex(index);
69 } 70 }
70 ui->room_description->setText(UISettings::values.room_description); 71 ui->room_description->setText(UISettings::values.multiplayer_room_description.GetValue());
71} 72}
72 73
73HostRoomWindow::~HostRoomWindow() = default; 74HostRoomWindow::~HostRoomWindow() = default;
@@ -91,7 +92,8 @@ std::unique_ptr<Network::VerifyUser::Backend> HostRoomWindow::CreateVerifyBacken
91 std::unique_ptr<Network::VerifyUser::Backend> verify_backend; 92 std::unique_ptr<Network::VerifyUser::Backend> verify_backend;
92 if (use_validation) { 93 if (use_validation) {
93#ifdef ENABLE_WEB_SERVICE 94#ifdef ENABLE_WEB_SERVICE
94 verify_backend = std::make_unique<WebService::VerifyUserJWT>(Settings::values.web_api_url); 95 verify_backend =
96 std::make_unique<WebService::VerifyUserJWT>(Settings::values.web_api_url.GetValue());
95#else 97#else
96 verify_backend = std::make_unique<Network::VerifyUser::NullBackend>(); 98 verify_backend = std::make_unique<Network::VerifyUser::NullBackend>();
97#endif 99#endif
@@ -137,7 +139,7 @@ void HostRoomWindow::Host() {
137 const bool is_public = ui->host_type->currentIndex() == 0; 139 const bool is_public = ui->host_type->currentIndex() == 0;
138 Network::Room::BanList ban_list{}; 140 Network::Room::BanList ban_list{};
139 if (ui->load_ban_list->isChecked()) { 141 if (ui->load_ban_list->isChecked()) {
140 ban_list = UISettings::values.ban_list; 142 ban_list = UISettings::values.multiplayer_ban_list;
141 } 143 }
142 if (auto room = Network::GetRoom().lock()) { 144 if (auto room = Network::GetRoom().lock()) {
143 bool created = room->Create( 145 bool created = room->Create(
@@ -181,8 +183,9 @@ void HostRoomWindow::Host() {
181 std::string token; 183 std::string token;
182#ifdef ENABLE_WEB_SERVICE 184#ifdef ENABLE_WEB_SERVICE
183 if (is_public) { 185 if (is_public) {
184 WebService::Client client(Settings::values.web_api_url, Settings::values.yuzu_username, 186 WebService::Client client(Settings::values.web_api_url.GetValue(),
185 Settings::values.yuzu_token); 187 Settings::values.yuzu_username.GetValue(),
188 Settings::values.yuzu_token.GetValue());
186 if (auto room = Network::GetRoom().lock()) { 189 if (auto room = Network::GetRoom().lock()) {
187 token = client.GetExternalJWT(room->GetVerifyUID()).returned_data; 190 token = client.GetExternalJWT(room->GetVerifyUID()).returned_data;
188 } 191 }
@@ -198,17 +201,19 @@ void HostRoomWindow::Host() {
198 Network::NoPreferredMac, password, token); 201 Network::NoPreferredMac, password, token);
199 202
200 // Store settings 203 // Store settings
201 UISettings::values.room_nickname = ui->username->text(); 204 UISettings::values.multiplayer_room_nickname = ui->username->text();
202 UISettings::values.room_name = ui->room_name->text(); 205 UISettings::values.multiplayer_room_name = ui->room_name->text();
203 UISettings::values.game_id = 206 UISettings::values.multiplayer_game_id =
204 ui->game_list->currentData(GameListItemPath::ProgramIdRole).toLongLong(); 207 ui->game_list->currentData(GameListItemPath::ProgramIdRole).toLongLong();
205 UISettings::values.max_player = ui->max_player->value(); 208 UISettings::values.multiplayer_max_player = ui->max_player->value();
206 209
207 UISettings::values.host_type = ui->host_type->currentIndex(); 210 UISettings::values.multiplayer_host_type = ui->host_type->currentIndex();
208 UISettings::values.room_port = (ui->port->isModified() && !ui->port->text().isEmpty()) 211 if (ui->port->isModified() && !ui->port->text().isEmpty()) {
209 ? ui->port->text() 212 UISettings::values.multiplayer_room_port = ui->port->text().toInt();
210 : QString::number(Network::DefaultRoomPort); 213 } else {
211 UISettings::values.room_description = ui->room_description->toPlainText(); 214 UISettings::values.multiplayer_room_port = Network::DefaultRoomPort;
215 }
216 UISettings::values.multiplayer_room_description = ui->room_description->toPlainText();
212 ui->host->setEnabled(true); 217 ui->host->setEnabled(true);
213 close(); 218 close();
214 } 219 }
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,
56 ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu); 56 ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu);
57 57
58 ui->nickname->setValidator(validation.GetNickname()); 58 ui->nickname->setValidator(validation.GetNickname());
59 ui->nickname->setText(UISettings::values.nickname); 59 ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue());
60 if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) { 60 if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
61 // Use yuzu Web Service user name as nickname by default 61 // Use yuzu Web Service user name as nickname by default
62 ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue())); 62 ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
@@ -154,9 +154,11 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
154 QFuture<void> f = QtConcurrent::run([nickname, ip, port, password, verify_UID] { 154 QFuture<void> f = QtConcurrent::run([nickname, ip, port, password, verify_UID] {
155 std::string token; 155 std::string token;
156#ifdef ENABLE_WEB_SERVICE 156#ifdef ENABLE_WEB_SERVICE
157 if (!Settings::values.yuzu_username.empty() && !Settings::values.yuzu_token.empty()) { 157 if (!Settings::values.yuzu_username.GetValue().empty() &&
158 WebService::Client client(Settings::values.web_api_url, Settings::values.yuzu_username, 158 !Settings::values.yuzu_token.GetValue().empty()) {
159 Settings::values.yuzu_token); 159 WebService::Client client(Settings::values.web_api_url.GetValue(),
160 Settings::values.yuzu_username.GetValue(),
161 Settings::values.yuzu_token.GetValue());
160 token = client.GetExternalJWT(verify_UID).returned_data; 162 token = client.GetExternalJWT(verify_UID).returned_data;
161 if (token.empty()) { 163 if (token.empty()) {
162 LOG_ERROR(WebService, "Could not get external JWT, verification may fail"); 164 LOG_ERROR(WebService, "Could not get external JWT, verification may fail");
@@ -175,9 +177,11 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
175 // TODO(jroweboy): disable widgets and display a connecting while we wait 177 // TODO(jroweboy): disable widgets and display a connecting while we wait
176 178
177 // Save settings 179 // Save settings
178 UISettings::values.nickname = ui->nickname->text(); 180 UISettings::values.multiplayer_nickname = ui->nickname->text();
179 UISettings::values.ip = proxy->data(connection_index, LobbyItemHost::HostIPRole).toString(); 181 UISettings::values.multiplayer_ip =
180 UISettings::values.port = proxy->data(connection_index, LobbyItemHost::HostPortRole).toString(); 182 proxy->data(connection_index, LobbyItemHost::HostIPRole).toString();
183 UISettings::values.multiplayer_port =
184 proxy->data(connection_index, LobbyItemHost::HostPortRole).toInt();
181} 185}
182 186
183void Lobby::ResetModel() { 187void 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() {
232 return true; 232 return true;
233 } 233 }
234 // Save ban list 234 // Save ban list
235 UISettings::values.ban_list = std::move(room->GetBanList()); 235 UISettings::values.multiplayer_ban_list = std::move(room->GetBanList());
236 236
237 room->Destroy(); 237 room->Destroy();
238 announce_multiplayer_session->Stop(); 238 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 {
103 Settings::Setting<uint32_t> callout_flags{0, "calloutFlags"}; 103 Settings::Setting<uint32_t> callout_flags{0, "calloutFlags"};
104 104
105 // multiplayer settings 105 // multiplayer settings
106 QString nickname; 106 Settings::Setting<QString> multiplayer_nickname{QStringLiteral("yuzu"), "nickname"};
107 QString ip; 107 Settings::Setting<QString> multiplayer_ip{{}, "ip"};
108 QString port; 108 Settings::SwitchableSetting<uint> multiplayer_port{24872, 0, 65535, "port"};
109 QString room_nickname; 109 Settings::Setting<QString> multiplayer_room_nickname{{}, "room_nickname"};
110 QString room_name; 110 Settings::Setting<QString> multiplayer_room_name{{}, "room_name"};
111 quint32 max_player; 111 Settings::SwitchableSetting<uint> multiplayer_max_player{8, 0, 8, "max_player"};
112 QString room_port; 112 Settings::SwitchableSetting<uint> multiplayer_room_port{24872, 0, 65535, "room_port"};
113 uint host_type; 113 Settings::SwitchableSetting<uint> multiplayer_host_type{0, 0, 1, "host_type"};
114 qulonglong game_id; 114 Settings::Setting<qulonglong> multiplayer_game_id{{}, "game_id"};
115 QString room_description; 115 Settings::Setting<QString> multiplayer_room_description{{}, "room_description"};
116 std::pair<std::vector<std::string>, std::vector<std::string>> ban_list; 116 std::pair<std::vector<std::string>, std::vector<std::string>> multiplayer_ban_list;
117 117
118 // logging 118 // logging
119 Settings::Setting<bool> show_console{false, "showConsole"}; 119 Settings::Setting<bool> show_console{false, "showConsole"};