feat: Add lobby API URL configuration and migrate from web_api_url

- Replace web_api_url references with lobby_api_url
- Add lobby API URL field to network configuration UI with restore default
- Add ReadNetworkValues/SaveNetworkValues to QtConfig for network settings
- Fix signed/unsigned comparison in lobby filter

Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
Zephyron
2025-12-06 16:38:45 +10:00
parent b5a82bcfdc
commit 2e7a4026d8
8 changed files with 81 additions and 14 deletions

View File

@@ -2,6 +2,7 @@
// SPDX-FileCopyrightText: Copyright 2025 Citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <QMessageBox>
#include <QtConcurrent/QtConcurrent>
#include "common/settings.h"
#include "core/core.h"
@@ -19,20 +20,26 @@ ConfigureNetwork::ConfigureNetwork(const Core::System& system_, QWidget* parent)
}
this->SetConfiguration();
// Store the initial URL
original_lobby_api_url = Settings::values.lobby_api_url.GetValue();
connect(ui->restore_default_lobby_api, &QPushButton::clicked, this, &ConfigureNetwork::OnRestoreDefaultLobbyApi);
}
ConfigureNetwork::~ConfigureNetwork() = default;
void ConfigureNetwork::ApplyConfiguration() {
// Apply all settings from the UI to the settings system
Settings::values.airplane_mode = ui->airplane_mode->isChecked();
Settings::values.network_interface = ui->network_interface->currentText().toStdString();
Settings::values.lobby_api_url = ui->lobby_api_url->text().toStdString();
}
void ConfigureNetwork::changeEvent(QEvent* event) {
if (event->type() == QEvent::LanguageChange) {
RetranslateUI();
}
QWidget::changeEvent(event);
}
@@ -47,11 +54,23 @@ void ConfigureNetwork::SetConfiguration() {
ui->airplane_mode->setEnabled(runtime_lock);
const std::string& network_interface = Settings::values.network_interface.GetValue();
ui->network_interface->setCurrentText(QString::fromStdString(network_interface));
ui->network_interface->setEnabled(runtime_lock && !ui->airplane_mode->isChecked());
connect(ui->airplane_mode, &QCheckBox::toggled, this, [this](bool checked) {
ui->network_interface->setEnabled(!checked && !system.IsPoweredOn());
ui->lobby_api_url->setText(QString::fromStdString(Settings::values.lobby_api_url.GetValue()));
const bool networking_enabled = runtime_lock && !ui->airplane_mode->isChecked();
ui->network_interface->setEnabled(networking_enabled);
ui->lobby_api_url->setEnabled(networking_enabled);
ui->restore_default_lobby_api->setEnabled(networking_enabled);
connect(ui->airplane_mode, &QCheckBox::toggled, this, [this, runtime_lock](bool checked) {
const bool enabled = !checked && runtime_lock;
ui->network_interface->setEnabled(enabled);
ui->lobby_api_url->setEnabled(enabled);
ui->restore_default_lobby_api->setEnabled(enabled);
});
}
void ConfigureNetwork::OnRestoreDefaultLobbyApi() {
ui->lobby_api_url->setText(QString::fromStdString(Settings::values.lobby_api_url.GetDefault()));
}

View File

@@ -1,15 +1,22 @@
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include <string> // Required for std::string
#include <QWidget>
namespace Ui {
class ConfigureNetwork;
}
// Forward declare Core::System
namespace Core {
class System;
}
class ConfigureNetwork : public QWidget {
Q_OBJECT
@@ -19,12 +26,17 @@ public:
void ApplyConfiguration();
private slots:
void OnRestoreDefaultLobbyApi();
private:
void changeEvent(QEvent*) override;
void RetranslateUI();
void SetConfiguration();
std::unique_ptr<Ui::ConfigureNetwork> ui;
const Core::System& system;
// This stores the URL
std::string original_lobby_api_url;
};

View File

@@ -25,7 +25,7 @@
<string>General</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="airplane_mode">
<property name="text">
<string>Airplane Mode</string>
@@ -45,6 +45,23 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_lobby_api">
<property name="text">
<string>Lobby API URL</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lobby_api_url"/>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="restore_default_lobby_api">
<property name="text">
<string>Restore Default</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -76,6 +76,7 @@ void QtConfig::ReadQtValues() {
ReadUIValues();
}
ReadQtControlValues();
ReadNetworkValues();
}
void QtConfig::ReadQtPlayerValues(const std::size_t player_index) {
@@ -279,6 +280,12 @@ void QtConfig::ReadUIValues() {
EndGroup();
}
void QtConfig::ReadNetworkValues() {
BeginGroup(Settings::TranslateCategory(Settings::Category::Network));
ReadCategory(Settings::Category::Network);
EndGroup();
}
void QtConfig::ReadUIGamelistValues() {
BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList));
@@ -337,6 +344,7 @@ void QtConfig::SaveQtValues() {
LOG_DEBUG(Config, "Saving Qt configuration values");
}
SaveQtControlValues();
SaveNetworkValues();
WriteToIni();
}
@@ -526,6 +534,12 @@ void QtConfig::SaveMultiplayerValues() {
EndGroup();
}
void QtConfig::SaveNetworkValues() {
BeginGroup(Settings::TranslateCategory(Settings::Category::Network));
WriteCategory(Settings::Category::Network);
EndGroup();
}
std::vector<Settings::BasicSetting*>& QtConfig::FindRelevantList(Settings::Category category) {
auto& map = Settings::values.linkage.by_category;
if (map.contains(category)) {

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -31,6 +32,7 @@ protected:
void ReadUIGamelistValues() override;
void ReadUILayoutValues() override;
void ReadMultiplayerValues() override;
void ReadNetworkValues();
void SaveQtValues();
void SaveQtPlayerValues(std::size_t player_index);
@@ -43,6 +45,7 @@ protected:
void SaveUIGamelistValues() override;
void SaveUILayoutValues() override;
void SaveMultiplayerValues() override;
void SaveNetworkValues();
std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override;

View File

@@ -101,7 +101,7 @@ std::unique_ptr<Network::VerifyUser::Backend> HostRoomWindow::CreateVerifyBacken
if (use_validation) {
#ifdef ENABLE_WEB_SERVICE
verify_backend =
std::make_unique<WebService::VerifyUserJWT>(Settings::values.web_api_url.GetValue());
std::make_unique<WebService::VerifyUserJWT>(Settings::values.lobby_api_url.GetValue());
#else
verify_backend = std::make_unique<Network::VerifyUser::NullBackend>();
#endif
@@ -209,7 +209,7 @@ void HostRoomWindow::Host() {
std::string token;
#ifdef ENABLE_WEB_SERVICE
if (is_public) {
WebService::Client client(Settings::values.web_api_url.GetValue(),
WebService::Client client(Settings::values.lobby_api_url.GetValue(),
Settings::values.citron_username.GetValue(),
Settings::values.citron_token.GetValue());
if (auto room = room_network.GetRoom().lock()) {

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <QInputDialog>
@@ -189,7 +190,7 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
#ifdef ENABLE_WEB_SERVICE
if (!Settings::values.citron_username.GetValue().empty() &&
!Settings::values.citron_token.GetValue().empty() && !verify_uid.empty()) {
WebService::Client client(Settings::values.web_api_url.GetValue(),
WebService::Client client(Settings::values.lobby_api_url.GetValue(),
Settings::values.citron_username.GetValue(),
Settings::values.citron_token.GetValue());
token = client.GetExternalJWT(verify_uid).returned_data;
@@ -396,14 +397,14 @@ bool LobbyFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& s
for (int r = 0; r < game_list->rowCount(); ++r) {
owned_games.append(QModelIndex(game_list->index(r, 0)));
}
auto current_id = sourceModel()->data(game_name, LobbyItemGame::TitleIDRole).toLongLong();
auto current_id = sourceModel()->data(game_name, LobbyItemGame::TitleIDRole).toULongLong();
if (current_id == 0) {
// TODO(jroweboy): homebrew often doesn't have a game id and this hides them
return false;
}
bool owned = false;
for (const auto& game : owned_games) {
auto game_id = game_list->data(game, GameListItemPath::ProgramIdRole).toLongLong();
auto game_id = game_list->data(game, GameListItemPath::ProgramIdRole).toULongLong();
if (current_id == game_id) {
owned = true;
}

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
// SPDX-FileCopyrightText: 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <chrono>
@@ -22,7 +23,7 @@ static constexpr std::chrono::seconds announce_time_interval(15);
AnnounceMultiplayerSession::AnnounceMultiplayerSession(Network::RoomNetwork& room_network_)
: room_network{room_network_} {
#ifdef ENABLE_WEB_SERVICE
backend = std::make_unique<WebService::RoomJson>(Settings::values.web_api_url.GetValue(),
backend = std::make_unique<WebService::RoomJson>(Settings::values.lobby_api_url.GetValue(),
Settings::values.citron_username.GetValue(),
Settings::values.citron_token.GetValue());
#else
@@ -155,7 +156,7 @@ void AnnounceMultiplayerSession::UpdateCredentials() {
ASSERT_MSG(!IsRunning(), "Credentials can only be updated when session is not running");
#ifdef ENABLE_WEB_SERVICE
backend = std::make_unique<WebService::RoomJson>(Settings::values.web_api_url.GetValue(),
backend = std::make_unique<WebService::RoomJson>(Settings::values.lobby_api_url.GetValue(),
Settings::values.citron_username.GetValue(),
Settings::values.citron_token.GetValue());
#endif