Merge branch 'dolphin-mpn' into master

This commit is contained in:
Nayla 2023-04-05 04:10:05 -04:00 committed by GitHub
commit f3669dbbd4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
903 changed files with 4243 additions and 386 deletions

View file

@ -63,61 +63,7 @@ void NetPlayBrowser::CreateWidgets()
{
auto* layout = new QVBoxLayout;
m_table_widget = new QTableWidget;
m_table_widget->setTabKeyNavigation(false);
m_table_widget->setSelectionBehavior(QAbstractItemView::SelectRows);
m_table_widget->setSelectionMode(QAbstractItemView::SingleSelection);
m_table_widget->setWordWrap(false);
m_region_combo = new QComboBox;
m_region_combo->addItem(tr("Any Region"));
for (const auto& region : NetPlayIndex::GetRegions())
{
m_region_combo->addItem(
tr("%1 (%2)").arg(tr(region.second.c_str())).arg(QString::fromStdString(region.first)),
QString::fromStdString(region.first));
}
m_region_combo->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
m_status_label = new QLabel;
m_button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
m_button_refresh = new NonDefaultQPushButton(tr("Refresh"));
m_edit_name = new QLineEdit;
m_edit_game_id = new QLineEdit;
m_check_hide_incompatible = new QCheckBox(tr("Hide Incompatible Sessions"));
m_check_hide_ingame = new QCheckBox(tr("Hide In-Game Sessions"));
m_check_hide_incompatible->setChecked(true);
m_radio_all = new QRadioButton(tr("Private and Public"));
m_radio_private = new QRadioButton(tr("Private"));
m_radio_public = new QRadioButton(tr("Public"));
m_radio_all->setChecked(true);
auto* filter_box = new QGroupBox(tr("Filters"));
auto* filter_layout = new QGridLayout;
filter_box->setLayout(filter_layout);
filter_layout->addWidget(new QLabel(tr("Region:")), 0, 0);
filter_layout->addWidget(m_region_combo, 0, 1, 1, -1);
filter_layout->addWidget(new QLabel(tr("Name:")), 1, 0);
filter_layout->addWidget(m_edit_name, 1, 1, 1, -1);
filter_layout->addWidget(new QLabel(tr("Game ID:")), 2, 0);
filter_layout->addWidget(m_edit_game_id, 2, 1, 1, -1);
filter_layout->addWidget(m_radio_all, 3, 1);
filter_layout->addWidget(m_radio_public, 3, 2);
filter_layout->addWidget(m_radio_private, 3, 3);
filter_layout->addItem(new QSpacerItem(4, 1, QSizePolicy::Expanding), 3, 4);
filter_layout->addWidget(m_check_hide_incompatible, 4, 1, 1, -1);
filter_layout->addWidget(m_check_hide_ingame, 5, 1, 1, -1);
layout->addWidget(m_table_widget);
layout->addWidget(filter_box);
layout->addWidget(m_status_label);
layout->addWidget(m_button_box);
@ -220,7 +166,7 @@ void NetPlayBrowser::UpdateList()
m_table_widget->clear();
m_table_widget->setColumnCount(7);
m_table_widget->setHorizontalHeaderLabels({tr("Region"), tr("Name"), tr("Password?"),
m_table_widget->setHorizontalHeaderLabels({tr("Name"), tr("Password?"),
tr("In-Game?"), tr("Game"), tr("Players"),
tr("Version")});
@ -239,26 +185,20 @@ void NetPlayBrowser::UpdateList()
{
const auto& entry = m_sessions[i];
auto* region = new QTableWidgetItem(QString::fromStdString(entry.region));
auto* name = new QTableWidgetItem(QString::fromStdString(entry.name));
auto* password = new QTableWidgetItem(entry.has_password ? tr("Yes") : tr("No"));
auto* in_game = new QTableWidgetItem(entry.in_game ? tr("Yes") : tr("No"));
auto* game_id = new QTableWidgetItem(QString::fromStdString(entry.game_id));
auto* player_count = new QTableWidgetItem(QStringLiteral("%1").arg(entry.player_count));
auto* version = new QTableWidgetItem(QString::fromStdString(entry.version));
const bool enabled = Common::GetScmDescStr() == entry.version;
for (const auto& item : {region, name, password, in_game, game_id, player_count, version})
for (const auto& item : {name, in_game, game_id, player_count})
item->setFlags(enabled ? Qt::ItemIsEnabled | Qt::ItemIsSelectable : Qt::NoItemFlags);
m_table_widget->setItem(i, 0, region);
m_table_widget->setItem(i, 1, name);
m_table_widget->setItem(i, 2, password);
m_table_widget->setItem(i, 3, in_game);
m_table_widget->setItem(i, 4, game_id);
m_table_widget->setItem(i, 5, player_count);
m_table_widget->setItem(i, 6, version);
m_table_widget->setItem(i, 2, in_game);
m_table_widget->setItem(i, 3, game_id);
m_table_widget->setItem(i, 4, player_count);
}
m_status_label->setText(
@ -377,8 +317,11 @@ void NetPlayBrowser::RestoreSettings()
else if (visibility == QStringLiteral("private"))
m_radio_private->setChecked(true);
m_check_hide_incompatible->setChecked(
m_check_hide_incompatible->setChecked(true);
m_check_hide_ingame->setChecked(true);
/* m_check_hide_incompatible->setChecked(
settings.value(QStringLiteral("netplaybrowser/hide_incompatible"), true).toBool());
m_check_hide_ingame->setChecked(
settings.value(QStringLiteral("netplaybrowser/hide_ingame")).toBool());
settings.value(QStringLiteral("netplaybrowser/hide_ingame")).toBool());*/
}

View file

@ -129,6 +129,12 @@ void NetPlayDialog::CreateMainLayout()
m_game_button = new QPushButton;
m_start_button = new QPushButton(tr("Start"));
m_buffer_size_box = new QSpinBox;
m_buffer_size_box->setToolTip(
tr("Set the buffer based on the ping. The buffer should be ping ÷ 8 (rounded up).\nFor a "
"simple method, "
"use 8 for 64 ping and less, 12 for 100 ping and less, and 16 for 150 ping and "
"less.\nGames above 150 ping will be very laggy and are not recommended for competitive "
"play."));
m_buffer_label = new QLabel(tr("Buffer:"));
m_quit_button = new QPushButton(tr("Quit"));
m_splitter = new QSplitter(Qt::Horizontal);
@ -922,7 +928,7 @@ void NetPlayDialog::OnPadBufferChanged(u32 buffer)
});
DisplayMessage(m_host_input_authority ? tr("Max buffer size changed to %1").arg(buffer) :
tr("Buffer size changed to %1").arg(buffer),
"darkcyan");
"orange");
m_buffer_size = static_cast<int>(buffer);
}

View file

@ -9,13 +9,19 @@
#include <QComboBox>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QHeaderView>
#include <QInputDialog>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QPushButton>
#include <QRadioButton>
#include <QSignalBlocker>
#include <QSpinBox>
#include <QTabWidget>
#include <QTableWidget>
#include <QTableWidgetItem>
#include "Core/Config/NetplaySettings.h"
#include "Core/NetPlayProto.h"
@ -25,6 +31,8 @@
#include "DolphinQt/QtUtils/UTF8CodePointCountValidator.h"
#include "DolphinQt/Settings.h"
#include "Common/Version.h"
#include "DolphinQt/NetPlay/NetPlayBrowser.h"
#include "UICommon/GameFile.h"
#include "UICommon/NetPlayIndex.h"
@ -37,16 +45,11 @@ NetPlaySetupDialog::NetPlaySetupDialog(const GameListModel& game_list_model, QWi
CreateMainLayout();
bool use_index = Config::Get(Config::NETPLAY_USE_INDEX);
std::string index_region = Config::Get(Config::NETPLAY_INDEX_REGION);
std::string index_name = Config::Get(Config::NETPLAY_INDEX_NAME);
std::string index_password = Config::Get(Config::NETPLAY_INDEX_PASSWORD);
std::string nickname = Config::Get(Config::NETPLAY_NICKNAME);
std::string traversal_choice = Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE);
int connect_port = Config::Get(Config::NETPLAY_CONNECT_PORT);
int host_port = Config::Get(Config::NETPLAY_HOST_PORT);
int host_listen_port = Config::Get(Config::NETPLAY_LISTEN_PORT);
bool enable_chunked_upload_limit = Config::Get(Config::NETPLAY_ENABLE_CHUNKED_UPLOAD_LIMIT);
u32 chunked_upload_limit = Config::Get(Config::NETPLAY_CHUNKED_UPLOAD_LIMIT);
#ifdef USE_UPNP
bool use_upnp = Config::Get(Config::NETPLAY_USE_UPNP);
@ -58,28 +61,41 @@ NetPlaySetupDialog::NetPlaySetupDialog(const GameListModel& game_list_model, QWi
m_connect_port_box->setValue(connect_port);
m_host_port_box->setValue(host_port);
m_host_force_port_box->setValue(host_listen_port);
m_host_force_port_box->setEnabled(false);
m_host_server_browser->setChecked(use_index);
m_host_server_region->setEnabled(use_index);
m_host_server_region->setCurrentIndex(
m_host_server_region->findData(QString::fromStdString(index_region)));
m_host_server_name->setEnabled(use_index);
m_host_server_name->setText(QString::fromStdString(index_name));
m_host_server_password->setEnabled(use_index);
m_host_server_password->setText(QString::fromStdString(index_password));
// Browser Stuff
const auto& settings = Settings::Instance().GetQSettings();
m_host_chunked_upload_limit_check->setChecked(enable_chunked_upload_limit);
m_host_chunked_upload_limit_box->setValue(chunked_upload_limit);
m_host_chunked_upload_limit_box->setEnabled(enable_chunked_upload_limit);
const QByteArray geometry =
settings.value(QStringLiteral("netplaybrowser/geometry")).toByteArray();
if (!geometry.isEmpty())
restoreGeometry(geometry);
const QString region = settings.value(QStringLiteral("netplaybrowser/region")).toString();
const bool valid_region = m_region_combo->findText(region) != -1;
if (valid_region)
m_region_combo->setCurrentText(region);
m_edit_name->setText(settings.value(QStringLiteral("netplaybrowser/name")).toString());
const QString visibility = settings.value(QStringLiteral("netplaybrowser/visibility")).toString();
if (visibility == QStringLiteral("public"))
m_radio_public->setChecked(true);
else if (visibility == QStringLiteral("private"))
m_radio_private->setChecked(true);
m_check_hide_ingame->setChecked(true);
OnConnectionTypeChanged(m_connection_type->currentIndex());
ConnectWidgets();
m_refresh_run.Set(true);
m_refresh_thread = std::thread([this] { RefreshLoopBrowser(); });
UpdateListBrowser();
RefreshBrowser();
}
void NetPlaySetupDialog::CreateMainLayout()
@ -88,7 +104,10 @@ void NetPlaySetupDialog::CreateMainLayout()
m_button_box = new QDialogButtonBox(QDialogButtonBox::Cancel);
m_nickname_edit = new QLineEdit;
m_connection_type = new QComboBox;
m_connection_type->setCurrentIndex(1);
m_reset_traversal_button = new NonDefaultQPushButton(tr("Reset Traversal Settings"));
m_tab_widget = new QTabWidget;
m_nickname_edit->setValidator(
@ -98,6 +117,50 @@ void NetPlaySetupDialog::CreateMainLayout()
auto* connection_widget = new QWidget;
auto* connection_layout = new QGridLayout;
// NetPlay Browser
auto* browser_widget = new QWidget;
auto* layout = new QVBoxLayout;
m_table_widget = new QTableWidget;
m_table_widget->setTabKeyNavigation(false);
m_table_widget->setSelectionBehavior(QAbstractItemView::SelectRows);
m_table_widget->setSelectionMode(QAbstractItemView::SingleSelection);
m_table_widget->setWordWrap(false);
m_region_combo = new QComboBox;
m_region_combo->addItem(tr("Any Region"));
for (const auto& region : NetPlayIndex::GetRegions())
{
m_region_combo->addItem(
tr("%1 (%2)").arg(tr(region.second.c_str())).arg(QString::fromStdString(region.first)),
QString::fromStdString(region.first));
}
m_region_combo->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
m_status_label = new QLabel;
m_b_button_box = new QDialogButtonBox;
m_button_refresh = new QPushButton(tr("Refresh"));
m_edit_name = new QLineEdit;
m_check_hide_ingame = new QCheckBox(tr("Hide In-Game Sessions"));
m_radio_all = new QRadioButton(tr("Private and Public"));
m_radio_private = new QRadioButton(tr("Private"));
m_radio_public = new QRadioButton(tr("Public"));
m_radio_all->setChecked(true);
layout->addWidget(m_table_widget);
layout->addWidget(m_status_label);
layout->addWidget(m_b_button_box);
m_b_button_box->addButton(m_button_refresh, QDialogButtonBox::ResetRole);
browser_widget->setLayout(layout);
m_ip_label = new QLabel;
m_ip_edit = new QLineEdit;
m_connect_port_label = new QLabel(tr("Port:"));
@ -113,7 +176,7 @@ void NetPlaySetupDialog::CreateMainLayout()
connection_layout->addWidget(
new QLabel(
tr("ALERT:\n\n"
"All players must use the same Dolphin version.\n"
"All players must use the same Dolphin version, unless Orange Dolphin is used to host\n"
"If enabled, SD cards must be identical between players.\n"
"If DSP LLE is used, DSP ROMs must be identical between players.\n"
"If a game is hanging on boot, it may not support Dual Core Netplay."
@ -130,16 +193,10 @@ void NetPlaySetupDialog::CreateMainLayout()
// Host widget
auto* host_widget = new QWidget;
auto* host_layout = new QGridLayout;
m_host_port_label = new QLabel(tr("Port:"));
m_host_port_box = new QSpinBox;
m_host_force_port_check = new QCheckBox(tr("Force Listen Port:"));
m_host_force_port_box = new QSpinBox;
m_host_chunked_upload_limit_check = new QCheckBox(tr("Limit Chunked Upload Speed:"));
m_host_chunked_upload_limit_box = new QSpinBox;
m_host_server_browser = new QCheckBox(tr("Show in server browser"));
m_host_server_name = new QLineEdit;
m_host_server_password = new QLineEdit;
m_host_server_region = new QComboBox;
#ifdef USE_UPNP
m_host_upnp = new QCheckBox(tr("Forward port (UPnP)"));
@ -148,41 +205,17 @@ void NetPlaySetupDialog::CreateMainLayout()
m_host_button = new NonDefaultQPushButton(tr("Host"));
m_host_port_box->setMaximum(65535);
m_host_force_port_box->setMaximum(65535);
m_host_chunked_upload_limit_box->setRange(1, 1000000);
m_host_chunked_upload_limit_box->setSingleStep(100);
m_host_chunked_upload_limit_box->setSuffix(QStringLiteral(" kbps"));
m_host_chunked_upload_limit_check->setToolTip(tr(
"This will limit the speed of chunked uploading per client, which is used for save sync."));
m_host_server_name->setToolTip(tr("Name of your session shown in the server browser"));
m_host_server_name->setPlaceholderText(tr("Name"));
m_host_server_password->setToolTip(tr("Password for joining your game (leave empty for none)"));
m_host_server_password->setPlaceholderText(tr("Password"));
for (const auto& region : NetPlayIndex::GetRegions())
{
m_host_server_region->addItem(
tr("%1 (%2)").arg(tr(region.second.c_str())).arg(QString::fromStdString(region.first)),
QString::fromStdString(region.first));
}
host_layout->addWidget(m_host_port_label, 0, 0);
host_layout->addWidget(m_host_port_box, 0, 1);
host_layout->addWidget(m_host_port_box, 0, 0, Qt::AlignLeft);
#ifdef USE_UPNP
host_layout->addWidget(m_host_upnp, 0, 2);
host_layout->addWidget(m_host_upnp, 0, 5, Qt::AlignRight);
#endif
host_layout->addWidget(m_host_server_browser, 1, 0);
host_layout->addWidget(m_host_server_region, 1, 1);
host_layout->addWidget(m_host_server_name, 1, 2);
host_layout->addWidget(m_host_server_password, 1, 3);
host_layout->addWidget(m_host_games, 2, 0, 1, -1);
host_layout->addWidget(m_host_force_port_check, 3, 0);
host_layout->addWidget(m_host_force_port_box, 3, 1, Qt::AlignLeft);
host_layout->addWidget(m_host_chunked_upload_limit_check, 4, 0);
host_layout->addWidget(m_host_chunked_upload_limit_box, 4, 1, Qt::AlignLeft);
host_layout->addWidget(m_host_button, 4, 3, 2, 1, Qt::AlignRight);
host_layout->addWidget(m_host_button, 4, 5, Qt::AlignRight);
host_widget->setLayout(host_layout);
@ -200,10 +233,21 @@ void NetPlaySetupDialog::CreateMainLayout()
// Tabs
m_tab_widget->addTab(connection_widget, tr("Connect"));
m_tab_widget->addTab(host_widget, tr("Host"));
m_tab_widget->addTab(browser_widget, tr("Browser"));
setLayout(m_main_layout);
}
NetPlaySetupDialog::~NetPlaySetupDialog()
{
m_refresh_run.Set(false);
m_refresh_event.Set();
if (m_refresh_thread.joinable())
m_refresh_thread.join();
SaveSettings();
}
void NetPlaySetupDialog::ConnectWidgets()
{
connect(m_connection_type, qOverload<int>(&QComboBox::currentIndexChanged), this,
@ -222,23 +266,12 @@ void NetPlaySetupDialog::ConnectWidgets()
m_host_games->item(index)->text());
});
// refresh browser on tab changed
connect(m_tab_widget, &QTabWidget::currentChanged, this, &NetPlaySetupDialog::RefreshBrowser);
connect(m_host_games, &QListWidget::itemDoubleClicked, this, &NetPlaySetupDialog::accept);
connect(m_host_force_port_check, &QCheckBox::toggled,
[this](bool value) { m_host_force_port_box->setEnabled(value); });
connect(m_host_chunked_upload_limit_check, &QCheckBox::toggled, this, [this](bool value) {
m_host_chunked_upload_limit_box->setEnabled(value);
SaveSettings();
});
connect(m_host_chunked_upload_limit_box, qOverload<int>(&QSpinBox::valueChanged), this,
&NetPlaySetupDialog::SaveSettings);
connect(m_host_server_browser, &QCheckBox::toggled, this, &NetPlaySetupDialog::SaveSettings);
connect(m_host_server_name, &QLineEdit::textChanged, this, &NetPlaySetupDialog::SaveSettings);
connect(m_host_server_password, &QLineEdit::textChanged, this, &NetPlaySetupDialog::SaveSettings);
connect(m_host_server_region,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&NetPlaySetupDialog::SaveSettings);
#ifdef USE_UPNP
connect(m_host_upnp, &QCheckBox::stateChanged, this, &NetPlaySetupDialog::SaveSettings);
@ -249,11 +282,26 @@ void NetPlaySetupDialog::ConnectWidgets()
connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(m_reset_traversal_button, &QPushButton::clicked, this,
&NetPlaySetupDialog::ResetTraversalHost);
connect(m_host_server_browser, &QCheckBox::toggled, this, [this](bool value) {
m_host_server_region->setEnabled(value);
m_host_server_name->setEnabled(value);
m_host_server_password->setEnabled(value);
});
// Browser Stuff
connect(m_region_combo, qOverload<int>(&QComboBox::currentIndexChanged), this,
&NetPlaySetupDialog::RefreshBrowser);
connect(m_button_refresh, &QPushButton::clicked, this, &NetPlaySetupDialog::RefreshBrowser);
connect(m_radio_all, &QRadioButton::toggled, this, &NetPlaySetupDialog::RefreshBrowser);
connect(m_radio_private, &QRadioButton::toggled, this, &NetPlaySetupDialog::RefreshBrowser);
connect(m_check_hide_ingame, &QRadioButton::toggled, this, &NetPlaySetupDialog::RefreshBrowser);
connect(m_edit_name, &QLineEdit::textChanged, this, &NetPlaySetupDialog::RefreshBrowser);
connect(m_table_widget, &QTableWidget::itemDoubleClicked, this,
&NetPlaySetupDialog::acceptBrowser);
connect(this, &NetPlaySetupDialog::UpdateStatusRequestedBrowser, this,
&NetPlaySetupDialog::OnUpdateStatusRequestedBrowser, Qt::QueuedConnection);
connect(this, &NetPlaySetupDialog::UpdateListRequestedBrowser, this,
&NetPlaySetupDialog::OnUpdateListRequestedBrowser, Qt::QueuedConnection);
}
void NetPlaySetupDialog::SaveSettings()
@ -271,21 +319,27 @@ void NetPlaySetupDialog::SaveSettings()
Config::SetBaseOrCurrent(Config::NETPLAY_USE_UPNP, m_host_upnp->isChecked());
#endif
if (m_host_force_port_check->isChecked())
Config::SetBaseOrCurrent(Config::NETPLAY_LISTEN_PORT,
static_cast<u16>(m_host_force_port_box->value()));
Config::SetBaseOrCurrent(Config::NETPLAY_ENABLE_CHUNKED_UPLOAD_LIMIT,
m_host_chunked_upload_limit_check->isChecked());
Config::SetBaseOrCurrent(Config::NETPLAY_CHUNKED_UPLOAD_LIMIT,
m_host_chunked_upload_limit_box->value());
Config::SetBaseOrCurrent(Config::NETPLAY_USE_INDEX, m_host_server_browser->isChecked());
Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_REGION,
m_host_server_region->currentData().toString().toStdString());
Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_REGION, "NA");
Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_NAME, m_host_server_name->text().toStdString());
Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_PASSWORD,
m_host_server_password->text().toStdString());
Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_PASSWORD, "");
// Browser Stuff
auto& settings = Settings::Instance().GetQSettings();
settings.setValue(QStringLiteral("netplaybrowser/geometry"), saveGeometry());
settings.setValue(QStringLiteral("netplaybrowser/region"), m_region_combo->currentText());
settings.setValue(QStringLiteral("netplaybrowser/name"), m_edit_name->text());
QString visibility(QStringLiteral("all"));
if (m_radio_public->isChecked())
visibility = QStringLiteral("public");
else if (m_radio_private->isChecked())
visibility = QStringLiteral("private");
settings.setValue(QStringLiteral("netplaybrowser/visibility"), visibility);
settings.setValue(QStringLiteral("netplaybrowser/hide_incompatible"), true);
settings.setValue(QStringLiteral("netplaybrowser/hide_ingame"), m_check_hide_ingame->isChecked());
}
void NetPlaySetupDialog::OnConnectionTypeChanged(int index)
@ -293,14 +347,10 @@ void NetPlaySetupDialog::OnConnectionTypeChanged(int index)
m_connect_port_box->setHidden(index != 0);
m_connect_port_label->setHidden(index != 0);
m_host_port_label->setHidden(index != 0);
m_host_port_box->setHidden(index != 0);
#ifdef USE_UPNP
m_host_upnp->setHidden(index != 0);
#endif
m_host_force_port_check->setHidden(index == 0);
m_host_force_port_box->setHidden(index == 0);
m_reset_traversal_button->setHidden(index == 0);
std::string address =
@ -315,6 +365,16 @@ void NetPlaySetupDialog::OnConnectionTypeChanged(int index)
void NetPlaySetupDialog::show()
{
// Here i'm setting the lobby name if it's empty to make
// NetPlay sessions start more easily for first time players
if (m_host_server_name->text().isEmpty())
{
std::string nickname = Config::Get(Config::NETPLAY_NICKNAME);
m_host_server_name->setText(QString::fromStdString(nickname));
}
m_connection_type->setCurrentIndex(1);
m_tab_widget->setCurrentIndex(2); // start on browser
PopulateGameList();
QDialog::show();
}
@ -335,20 +395,6 @@ void NetPlaySetupDialog::accept()
return;
}
if (m_host_server_browser->isChecked() && m_host_server_name->text().isEmpty())
{
ModalMessageBox::critical(this, tr("Error"), tr("You must provide a name for your session!"));
return;
}
if (m_host_server_browser->isChecked() &&
m_host_server_region->currentData().toString().isEmpty())
{
ModalMessageBox::critical(this, tr("Error"),
tr("You must provide a region for your session!"));
return;
}
emit Host(*items[0]->data(Qt::UserRole).value<std::shared_ptr<const UICommon::GameFile>>());
}
}
@ -391,3 +437,176 @@ void NetPlaySetupDialog::ResetTraversalHost()
.arg(QString::fromStdString(Config::NETPLAY_TRAVERSAL_SERVER.GetDefaultValue()),
QString::number(Config::NETPLAY_TRAVERSAL_PORT.GetDefaultValue())));
}
void NetPlaySetupDialog::RefreshBrowser()
{
std::map<std::string, std::string> filters;
if (!m_edit_name->text().isEmpty())
filters["name"] = m_edit_name->text().toStdString();
if (true)
filters["version"] = Common::GetScmDescStr();
if (!m_radio_all->isChecked())
filters["password"] = std::to_string(m_radio_private->isChecked());
if (m_region_combo->currentIndex() != 0)
filters["region"] = m_region_combo->currentData().toString().toStdString();
if (m_check_hide_ingame->isChecked())
filters["in_game"] = "0";
std::unique_lock<std::mutex> lock(m_refresh_filters_mutex);
m_refresh_filters = std::move(filters);
m_refresh_event.Set();
SaveSettings();
}
void NetPlaySetupDialog::RefreshLoopBrowser()
{
while (m_refresh_run.IsSet())
{
m_refresh_event.Wait();
std::unique_lock<std::mutex> lock(m_refresh_filters_mutex);
if (m_refresh_filters)
{
auto filters = std::move(*m_refresh_filters);
m_refresh_filters.reset();
lock.unlock();
emit UpdateStatusRequestedBrowser(tr("Refreshing..."));
NetPlayIndex client;
auto entries = client.List(filters);
if (entries)
{
emit UpdateListRequestedBrowser(std::move(*entries));
}
else
{
emit UpdateStatusRequestedBrowser(tr("Error obtaining session list: %1")
.arg(QString::fromStdString(client.GetLastError())));
}
}
}
}
void NetPlaySetupDialog::UpdateListBrowser()
{
const int session_count = static_cast<int>(m_sessions.size());
m_table_widget->clear();
m_table_widget->setColumnCount(4);
m_table_widget->setHorizontalHeaderLabels({
tr("Name"),
tr("Game"),
tr("Players"),
tr("In-Game"),
});
auto* hor_header = m_table_widget->horizontalHeader();
hor_header->setSectionResizeMode(0, QHeaderView::Stretch);
hor_header->setSectionResizeMode(0, QHeaderView::Stretch);
hor_header->setSectionResizeMode(1, QHeaderView::Stretch);
hor_header->setSectionResizeMode(2, QHeaderView::ResizeToContents);
hor_header->setSectionResizeMode(3, QHeaderView::ResizeToContents);
hor_header->setHighlightSections(false);
m_table_widget->setRowCount(session_count);
for (int i = 0; i < session_count; i++)
{
const auto& entry = m_sessions[i];
auto* name = new QTableWidgetItem(QString::fromStdString(entry.name));
auto* in_game = new QTableWidgetItem(entry.in_game ? tr("Yes") : tr("No"));
auto* game_id = new QTableWidgetItem(QString::fromStdString(entry.game_id));
auto* player_count = new QTableWidgetItem(QStringLiteral("%1").arg(entry.player_count));
const bool enabled = Common::GetScmDescStr() == entry.version;
for (const auto& item : {name, game_id, player_count, in_game})
item->setFlags(enabled ? Qt::ItemIsEnabled | Qt::ItemIsSelectable : Qt::NoItemFlags);
m_table_widget->setItem(i, 0, name);
m_table_widget->setItem(i, 1, game_id);
m_table_widget->setItem(i, 2, player_count);
m_table_widget->setItem(i, 3, in_game);
}
m_status_label->setText(
(session_count == 1 ? tr("%1 session found") : tr("%1 sessions found")).arg(session_count));
}
void NetPlaySetupDialog::OnSelectionChangedBrowser()
{
return;
}
void NetPlaySetupDialog::OnUpdateStatusRequestedBrowser(const QString& status)
{
m_status_label->setText(status);
}
void NetPlaySetupDialog::OnUpdateListRequestedBrowser(std::vector<NetPlaySession> sessions)
{
m_sessions = std::move(sessions);
UpdateListBrowser();
}
void NetPlaySetupDialog::acceptBrowser()
{
if (m_table_widget->selectedItems().isEmpty())
return;
const int index = m_table_widget->selectedItems()[0]->row();
NetPlaySession& session = m_sessions[index];
std::string server_id = session.server_id;
if (m_sessions[index].has_password)
{
auto* dialog = new QInputDialog(this);
dialog->setWindowFlags(dialog->windowFlags() & ~Qt::WindowContextHelpButtonHint);
dialog->setWindowTitle(tr("Enter password"));
dialog->setLabelText(tr("This session requires a password:"));
dialog->setWindowModality(Qt::WindowModal);
dialog->setTextEchoMode(QLineEdit::Password);
if (dialog->exec() != QDialog::Accepted)
return;
const std::string password = dialog->textValue().toStdString();
auto decrypted_id = session.DecryptID(password);
if (!decrypted_id)
{
ModalMessageBox::warning(this, tr("Error"), tr("Invalid password provided."));
return;
}
server_id = decrypted_id.value();
}
QDialog::accept();
Config::SetBaseOrCurrent(Config::NETPLAY_TRAVERSAL_CHOICE, session.method);
Config::SetBaseOrCurrent(Config::NETPLAY_CONNECT_PORT, session.port);
if (session.method == "traversal")
Config::SetBaseOrCurrent(Config::NETPLAY_HOST_CODE, server_id);
else
Config::SetBaseOrCurrent(Config::NETPLAY_ADDRESS, server_id);
emit JoinBrowser();
}

View file

@ -6,6 +6,7 @@
#include <QDialog>
#include "DolphinQt/GameList/GameListModel.h"
#include "UICommon/NetPlayIndex.h"
class QCheckBox;
class QComboBox;
@ -17,6 +18,9 @@ class QGridLayout;
class QPushButton;
class QSpinBox;
class QTabWidget;
class QGroupBox;
class QTableWidget;
class QRadioButton;
namespace UICommon
{
@ -28,13 +32,17 @@ class NetPlaySetupDialog : public QDialog
Q_OBJECT
public:
explicit NetPlaySetupDialog(const GameListModel& game_list_model, QWidget* parent);
~NetPlaySetupDialog();
void accept() override;
void show();
signals:
bool Join();
void JoinBrowser();
bool Host(const UICommon::GameFile& game);
void UpdateStatusRequestedBrowser(const QString& status);
void UpdateListRequestedBrowser(std::vector<NetPlaySession> sessions);
private:
void CreateMainLayout();
@ -42,6 +50,15 @@ private:
void PopulateGameList();
void ResetTraversalHost();
// Browser Stuff
void RefreshBrowser();
void RefreshLoopBrowser();
void UpdateListBrowser();
void OnSelectionChangedBrowser();
void OnUpdateStatusRequestedBrowser(const QString& status);
void OnUpdateListRequestedBrowser(std::vector<NetPlaySession> sessions);
void acceptBrowser();
void SaveSettings();
void OnConnectionTypeChanged(int index);
@ -62,18 +79,32 @@ private:
QPushButton* m_connect_button;
// Host Widget
QLabel* m_host_port_label;
QSpinBox* m_host_port_box;
QListWidget* m_host_games;
QPushButton* m_host_button;
QCheckBox* m_host_force_port_check;
QSpinBox* m_host_force_port_box;
QCheckBox* m_host_chunked_upload_limit_check;
QSpinBox* m_host_chunked_upload_limit_box;
QCheckBox* m_host_server_browser;
QLineEdit* m_host_server_name;
QLineEdit* m_host_server_password;
QComboBox* m_host_server_region;
QTableWidget* m_table_widget;
QComboBox* m_region_combo;
QLabel* m_status_label;
QDialogButtonBox* m_b_button_box;
QPushButton* m_button_refresh;
QLineEdit* m_edit_name;
QCheckBox* m_check_hide_ingame;
QRadioButton* m_radio_all;
QRadioButton* m_radio_private;
QRadioButton* m_radio_public;
std::vector<NetPlaySession> m_sessions;
std::thread m_refresh_thread;
std::optional<std::map<std::string, std::string>> m_refresh_filters;
std::mutex m_refresh_filters_mutex;
Common::Flag m_refresh_run;
Common::Event m_refresh_event;
#ifdef USE_UPNP
QCheckBox* m_host_upnp;