diff options
| author | JosJuice <josjuice@gmail.com> | 2020-06-07 22:58:03 +0200 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2020-08-02 22:46:53 +0200 |
| commit | a41166bb376820389d9863ce23cf6fab20cb3b5f (patch) | |
| tree | 833fb8c0479af02a23f88d650838d542fa012b00 /Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp | |
| parent | 25ebc3c07c6310924d662b2209f9ba5d08006ea6 (diff) | |
Make netplay's "same game" check more robust
Instead of comparing the game ID, revision, disc number and name,
we can compare a hash of important parts of the disc including
all the aforementioned data but also additional data such as the
FST. The primary reason why I'm making this change is to let us
catch more desyncs before they happen, but this should also fix
https://bugs.dolphin-emu.org/issues/12115. As a bonus, the UI can
now distinguish the case where a client doesn't have the game at
all from the case where a client has the wrong version of the game.
Diffstat (limited to 'Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp')
| -rw-r--r-- | Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp | 97 |
1 files changed, 54 insertions, 43 deletions
diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp index 77ceb45523..82d2f0b141 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp @@ -21,6 +21,7 @@ #include <QTableWidget> #include <QTextBrowser> +#include <algorithm> #include <sstream> #include "Common/CommonPaths.h" @@ -37,6 +38,7 @@ #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/NetPlayServer.h" +#include "Core/SyncIdentifier.h" #include "DolphinQt/GameList/GameListModel.h" #include "DolphinQt/NetPlay/ChunkedProgressDialog.h" @@ -153,17 +155,19 @@ void NetPlayDialog::CreateMainLayout() m_md5_menu = m_menu_bar->addMenu(tr("Checksum")); m_md5_menu->addAction(tr("Current game"), this, [this] { - Settings::Instance().GetNetPlayServer()->ComputeMD5(m_current_game); + Settings::Instance().GetNetPlayServer()->ComputeMD5(m_current_game_identifier); }); m_md5_menu->addAction(tr("Other game..."), this, [this] { GameListDialog gld(this); if (gld.exec() != QDialog::Accepted) return; - Settings::Instance().GetNetPlayServer()->ComputeMD5(gld.GetSelectedUniqueID().toStdString()); + Settings::Instance().GetNetPlayServer()->ComputeMD5(gld.GetSelectedGame().GetSyncIdentifier()); + }); + m_md5_menu->addAction(tr("SD Card"), this, [] { + Settings::Instance().GetNetPlayServer()->ComputeMD5( + NetPlay::NetPlayClient::GetSDCardIdentifier()); }); - m_md5_menu->addAction(tr("SD Card"), this, - [] { Settings::Instance().GetNetPlayServer()->ComputeMD5(WII_SDCARD); }); m_other_menu = m_menu_bar->addMenu(tr("Other")); m_record_input_action = m_other_menu->addAction(tr("Record Inputs")); @@ -321,9 +325,11 @@ void NetPlayDialog::ConnectWidgets() GameListDialog gld(this); if (gld.exec() == QDialog::Accepted) { - auto unique_id = gld.GetSelectedUniqueID(); - Settings::Instance().GetNetPlayServer()->ChangeGame(unique_id.toStdString()); - Settings::GetQSettings().setValue(QStringLiteral("netplay/hostgame"), unique_id); + const UICommon::GameFile& game = gld.GetSelectedGame(); + const std::string netplay_name = game.GetNetPlayName(); + Settings::Instance().GetNetPlayServer()->ChangeGame(game.GetSyncIdentifier(), netplay_name); + Settings::GetQSettings().setValue(QStringLiteral("netplay/hostgame"), + QString::fromStdString(netplay_name)); } }); @@ -416,7 +422,7 @@ void NetPlayDialog::OnStart() return; } - const auto game = FindGameFile(m_current_game); + const auto game = FindGameFile(m_current_game_identifier); if (!game) { PanicAlertT("Selected game doesn't exist in game list!"); @@ -583,11 +589,12 @@ void NetPlayDialog::UpdateDiscordPresence() { #ifdef USE_DISCORD_PRESENCE // both m_current_game and m_player_count need to be set for the status to be displayed correctly - if (m_player_count == 0 || m_current_game.empty()) + if (m_player_count == 0 || m_current_game_name.empty()) return; const auto use_default = [this]() { - Discord::UpdateDiscordPresence(m_player_count, Discord::SecretType::Empty, "", m_current_game); + Discord::UpdateDiscordPresence(m_player_count, Discord::SecretType::Empty, "", + m_current_game_name); }; if (Core::IsRunning()) @@ -602,7 +609,8 @@ void NetPlayDialog::UpdateDiscordPresence() return use_default(); Discord::UpdateDiscordPresence(m_player_count, Discord::SecretType::RoomID, - std::string(host_id.begin(), host_id.end()), m_current_game); + std::string(host_id.begin(), host_id.end()), + m_current_game_name); } else { @@ -612,7 +620,7 @@ void NetPlayDialog::UpdateDiscordPresence() Discord::UpdateDiscordPresence( m_player_count, Discord::SecretType::IPAddress, - Discord::CreateSecretFromIPAddress(*m_external_ip_address, port), m_current_game); + Discord::CreateSecretFromIPAddress(*m_external_ip_address, port), m_current_game_name); } } else @@ -660,9 +668,10 @@ void NetPlayDialog::UpdateGUI() return '|' + str + '|'; }; - static const std::map<NetPlay::PlayerGameStatus, QString> player_status{ - {NetPlay::PlayerGameStatus::Ok, tr("OK")}, - {NetPlay::PlayerGameStatus::NotFound, tr("Not Found")}, + static const std::map<NetPlay::SyncIdentifierComparison, QString> player_status{ + {NetPlay::SyncIdentifierComparison::SameGame, tr("OK")}, + {NetPlay::SyncIdentifierComparison::DifferentVersion, tr("Wrong Version")}, + {NetPlay::SyncIdentifierComparison::DifferentGame, tr("Not Found")}, }; for (int i = 0; i < m_player_count; i++) @@ -805,15 +814,17 @@ void NetPlayDialog::AppendChat(const std::string& msg) QApplication::alert(this); } -void NetPlayDialog::OnMsgChangeGame(const std::string& title) +void NetPlayDialog::OnMsgChangeGame(const NetPlay::SyncIdentifier& sync_identifier, + const std::string& netplay_name) { - QString qtitle = QString::fromStdString(title); - QueueOnObject(this, [this, qtitle, title] { - m_game_button->setText(qtitle); - m_current_game = title; + QString qname = QString::fromStdString(netplay_name); + QueueOnObject(this, [this, qname, netplay_name, &sync_identifier] { + m_game_button->setText(qname); + m_current_game_identifier = sync_identifier; + m_current_game_name = netplay_name; UpdateDiscordPresence(); }); - DisplayMessage(tr("Game changed to \"%1\"").arg(qtitle), "magenta"); + DisplayMessage(tr("Game changed to \"%1\"").arg(qname), "magenta"); } void NetPlayDialog::GameStatusChanged(bool running) @@ -859,7 +870,12 @@ void NetPlayDialog::OnMsgStartGame() auto client = Settings::Instance().GetNetPlayClient(); if (client) - client->StartGame(FindGame(m_current_game)); + { + if (auto game = FindGameFile(m_current_game_identifier)) + client->StartGame(game->GetFilePath()); + else + PanicAlertT("Selected game doesn't exist in game list!"); + } UpdateDiscordPresence(); }); } @@ -1017,29 +1033,24 @@ bool NetPlayDialog::IsRecording() return false; } -std::string NetPlayDialog::FindGame(const std::string& game) +std::shared_ptr<const UICommon::GameFile> +NetPlayDialog::FindGameFile(const NetPlay::SyncIdentifier& sync_identifier, + NetPlay::SyncIdentifierComparison* found) { - std::optional<std::string> path = RunOnObject(this, [this, &game] { - for (int i = 0; i < m_game_list_model->rowCount(QModelIndex()); i++) - { - if (m_game_list_model->GetUniqueIdentifier(i).toStdString() == game) - return m_game_list_model->GetPath(i).toStdString(); - } - return std::string(""); - }); - if (path) - return *path; - return std::string(""); -} + NetPlay::SyncIdentifierComparison temp; + if (!found) + found = &temp; + + *found = NetPlay::SyncIdentifierComparison::DifferentGame; -std::shared_ptr<const UICommon::GameFile> NetPlayDialog::FindGameFile(const std::string& game) -{ std::optional<std::shared_ptr<const UICommon::GameFile>> game_file = - RunOnObject(this, [this, &game] { + RunOnObject(this, [this, &sync_identifier, found] { for (int i = 0; i < m_game_list_model->rowCount(QModelIndex()); i++) { - if (m_game_list_model->GetUniqueIdentifier(i).toStdString() == game) - return m_game_list_model->GetGameFile(i); + auto game_file = m_game_list_model->GetGameFile(i); + *found = std::min(*found, game_file->CompareSyncIdentifier(sync_identifier)); + if (*found == NetPlay::SyncIdentifierComparison::SameGame) + return game_file; } return static_cast<std::shared_ptr<const UICommon::GameFile>>(nullptr); }); @@ -1126,15 +1137,15 @@ void NetPlayDialog::SaveSettings() Config::SetBase(Config::NETPLAY_NETWORK_MODE, network_mode); } -void NetPlayDialog::ShowMD5Dialog(const std::string& file_identifier) +void NetPlayDialog::ShowMD5Dialog(const std::string& title) { - QueueOnObject(this, [this, file_identifier] { + QueueOnObject(this, [this, title] { m_md5_menu->setEnabled(false); if (m_md5_dialog->isVisible()) m_md5_dialog->close(); - m_md5_dialog->show(QString::fromStdString(file_identifier)); + m_md5_dialog->show(QString::fromStdString(title)); }); } |
