Port multiplayer related PRs from yuzu (yuzu-emu/yuzu#9661 and yuzu-emu/yuzu#9713) (#6319)

Co-authored-by: SoRadGaming <sohorhab.azizdel@outlook.com>
Co-authored-by: Luke Sawczak <luke@unfamiliarplace.com>
This commit is contained in:
Tobias 2023-03-08 00:51:46 +01:00 committed by GitHub
parent 455a0198d9
commit 07e02a1acf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 33 deletions

View file

@ -70,20 +70,13 @@ void DirectConnectWindow::Connect() {
} }
} }
} }
switch (static_cast<ConnectionType>(ui->connection_type->currentIndex())) { if (!ui->ip->hasAcceptableInput()) {
case ConnectionType::TraversalServer: NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::IP_ADDRESS_NOT_VALID);
break; return;
case ConnectionType::IP: }
if (!ui->ip->hasAcceptableInput()) { if (!ui->port->hasAcceptableInput()) {
NetworkMessage::ErrorManager::ShowError( NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::PORT_NOT_VALID);
NetworkMessage::ErrorManager::IP_ADDRESS_NOT_VALID); return;
return;
}
if (!ui->port->hasAcceptableInput()) {
NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::PORT_NOT_VALID);
return;
}
break;
} }
// Store settings // Store settings

View file

@ -26,20 +26,11 @@
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<widget class="QComboBox" name="connection_type">
<item>
<property name="text">
<string>IP Address</string>
</property>
</item>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="ip_container" native="true"> <widget class="QWidget" name="ip_container" native="true">
<layout class="QHBoxLayout" name="ip_layout"> <layout class="QHBoxLayout" name="ip_layout">
<property name="leftMargin"> <property name="leftMargin">
<number>5</number> <number>0</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>0</number>
@ -53,17 +44,17 @@
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>IP</string> <string>Server Address</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="ip"> <widget class="QLineEdit" name="ip">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;IPv4 address of the host&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Server address of the host&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="maxLength"> <property name="maxLength">
<number>16</number> <number>253</number>
</property> </property>
</widget> </widget>
</item> </item>
@ -85,6 +76,12 @@
<property name="placeholderText"> <property name="placeholderText">
<string>24872</string> <string>24872</string>
</property> </property>
<property name="maximumSize">
<size>
<width>65</width>
<height>50</height>
</size>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>

View file

@ -66,6 +66,7 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
// UI Buttons // UI Buttons
connect(ui->refresh_list, &QPushButton::clicked, this, &Lobby::RefreshLobby); connect(ui->refresh_list, &QPushButton::clicked, this, &Lobby::RefreshLobby);
connect(ui->games_owned, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterOwned); connect(ui->games_owned, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterOwned);
connect(ui->hide_empty, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterEmpty);
connect(ui->hide_full, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterFull); connect(ui->hide_full, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterFull);
connect(ui->search, &QLineEdit::textChanged, proxy, &LobbyFilterProxyModel::SetFilterSearch); connect(ui->search, &QLineEdit::textChanged, proxy, &LobbyFilterProxyModel::SetFilterSearch);
connect(ui->room_list, &QTreeView::doubleClicked, this, &Lobby::OnJoinRoom); connect(ui->room_list, &QTreeView::doubleClicked, this, &Lobby::OnJoinRoom);
@ -282,12 +283,22 @@ bool LobbyFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& s
return true; return true;
} }
// filter by empty rooms
if (filter_empty) {
QModelIndex member_list = sourceModel()->index(sourceRow, Column::MEMBER, sourceParent);
const int player_count =
sourceModel()->data(member_list, LobbyItemMemberList::MemberListRole).toList().size();
if (player_count == 0) {
return false;
}
}
// filter by filled rooms // filter by filled rooms
if (filter_full) { if (filter_full) {
QModelIndex member_list = sourceModel()->index(sourceRow, Column::MEMBER, sourceParent); QModelIndex member_list = sourceModel()->index(sourceRow, Column::MEMBER, sourceParent);
int player_count = const int player_count =
sourceModel()->data(member_list, LobbyItemMemberList::MemberListRole).toList().size(); sourceModel()->data(member_list, LobbyItemMemberList::MemberListRole).toList().size();
int max_players = const int max_players =
sourceModel()->data(member_list, LobbyItemMemberList::MaxPlayerRole).toInt(); sourceModel()->data(member_list, LobbyItemMemberList::MaxPlayerRole).toInt();
if (player_count >= max_players) { if (player_count >= max_players) {
return false; return false;
@ -352,6 +363,11 @@ void LobbyFilterProxyModel::SetFilterOwned(bool filter) {
invalidate(); invalidate();
} }
void LobbyFilterProxyModel::SetFilterEmpty(bool filter) {
filter_empty = filter;
invalidate();
}
void LobbyFilterProxyModel::SetFilterFull(bool filter) { void LobbyFilterProxyModel::SetFilterFull(bool filter) {
filter_full = filter; filter_full = filter;
invalidate(); invalidate();

View file

@ -116,12 +116,14 @@ public:
public slots: public slots:
void SetFilterOwned(bool); void SetFilterOwned(bool);
void SetFilterEmpty(bool);
void SetFilterFull(bool); void SetFilterFull(bool);
void SetFilterSearch(const QString&); void SetFilterSearch(const QString&);
private: private:
QStandardItemModel* game_list; QStandardItemModel* game_list;
bool filter_owned = false; bool filter_owned = false;
bool filter_empty = false;
bool filter_full = false; bool filter_full = false;
QString filter_search; QString filter_search;
}; };

View file

@ -77,6 +77,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="hide_empty">
<property name="text">
<string>Hide Empty Rooms</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QCheckBox" name="hide_full"> <widget class="QCheckBox" name="hide_full">
<property name="text"> <property name="text">

View file

@ -37,11 +37,28 @@ private:
QRegExp nickname_regex = QRegExp(QStringLiteral("^[a-zA-Z0-9._- ]{4,20}$")); QRegExp nickname_regex = QRegExp(QStringLiteral("^[a-zA-Z0-9._- ]{4,20}$"));
QRegExpValidator nickname; QRegExpValidator nickname;
/// ipv4 address only /// ipv4 / ipv6 / hostnames
// TODO remove this when we support hostnames in direct connect
QRegExp ip_regex = QRegExp(QStringLiteral( QRegExp ip_regex = QRegExp(QStringLiteral(
"(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|" // IPv4 regex
"2[0-4][0-9]|25[0-5])")); "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|"
// IPv6 regex
"^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|"
"(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-"
"5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|"
"(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)"
"(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|"
"(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]"
"\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|"
"(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2["
"0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|"
"(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2["
"0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|"
"(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2["
"0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|"
"(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?"
"\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?$|"
// Hostname regex
"^([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\\.)+[a-zA-Z]{2,}$"));
QRegExpValidator ip; QRegExpValidator ip;
/// port must be between 0 and 65535 /// port must be between 0 and 65535