Check if all players have the game before starting netplay

https://bugs.dolphin-emu.org/issues/8885
This commit is contained in:
Aestek 2016-07-10 10:13:34 +02:00
parent 7ee6d08213
commit cd9a58b704
7 changed files with 116 additions and 7 deletions

View File

@ -356,6 +356,33 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
// update gui // update gui
m_dialog->OnMsgChangeGame(m_selected_game); m_dialog->OnMsgChangeGame(m_selected_game);
sf::Packet spac;
spac << static_cast<MessageId>(NP_MSG_GAME_STATUS);
PlayerGameStatus status = m_dialog->FindGame(m_selected_game).empty() ?
PlayerGameStatus::NotFound :
PlayerGameStatus::Ok;
spac << static_cast<u32>(status);
Send(spac);
}
break;
case NP_MSG_GAME_STATUS:
{
PlayerId pid;
packet >> pid;
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
Player& player = m_players[pid];
u32 status;
packet >> status;
player.game_status = static_cast<PlayerGameStatus>(status);
}
m_dialog->Update();
} }
break; break;
@ -597,7 +624,26 @@ void NetPlayClient::GetPlayerList(std::string& list, std::vector<int>& pid_list)
enumerate_player_controller_mappings(m_pad_map, player); enumerate_player_controller_mappings(m_pad_map, player);
enumerate_player_controller_mappings(m_wiimote_map, player); enumerate_player_controller_mappings(m_wiimote_map, player);
ss << " |\nPing: " << player.ping << "ms\n\n"; ss << " |\nPing: " << player.ping << "ms\n";
ss << "Status: ";
switch (player.game_status)
{
case PlayerGameStatus::Ok:
ss << "ready";
break;
case PlayerGameStatus::NotFound:
ss << "game missing";
break;
default:
ss << "unknown";
break;
}
ss << "\n\n";
pid_list.push_back(player.pid); pid_list.push_back(player.pid);
} }
@ -1143,6 +1189,14 @@ void NetPlayClient::SendTimeBase()
netplay_client->SendAsync(std::move(spac)); netplay_client->SendAsync(std::move(spac));
} }
bool NetPlayClient::DoAllPlayersHaveGame()
{
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
return std::all_of(std::begin(m_players), std::end(m_players),
[](auto entry) { return entry.second.game_status == PlayerGameStatus::Ok; });
}
// stuff hacked into dolphin // stuff hacked into dolphin
// called from ---CPU--- thread // called from ---CPU--- thread

View File

@ -33,6 +33,14 @@ public:
virtual void OnMsgStartGame() = 0; virtual void OnMsgStartGame() = 0;
virtual void OnMsgStopGame() = 0; virtual void OnMsgStopGame() = 0;
virtual bool IsRecording() = 0; virtual bool IsRecording() = 0;
virtual std::string FindGame(const std::string& game) = 0;
};
enum class PlayerGameStatus
{
Unknown,
Ok,
NotFound
}; };
class Player class Player
@ -42,6 +50,7 @@ public:
std::string name; std::string name;
std::string revision; std::string revision;
u32 ping; u32 ping;
PlayerGameStatus game_status;
}; };
class NetPlayClient : public TraversalClientClient class NetPlayClient : public TraversalClientClient
@ -83,6 +92,7 @@ public:
u8 LocalWiimoteToInGameWiimote(u8 local_pad); u8 LocalWiimoteToInGameWiimote(u8 local_pad);
static void SendTimeBase(); static void SendTimeBase();
bool DoAllPlayersHaveGame();
protected: protected:
void ClearBuffers(); void ClearBuffers();

View File

@ -53,6 +53,7 @@ enum
NP_MSG_CHANGE_GAME = 0xA1, NP_MSG_CHANGE_GAME = 0xA1,
NP_MSG_STOP_GAME = 0xA2, NP_MSG_STOP_GAME = 0xA2,
NP_MSG_DISABLE_GAME = 0xA3, NP_MSG_DISABLE_GAME = 0xA3,
NP_MSG_GAME_STATUS = 0xA4,
NP_MSG_TIMEBASE = 0xB0, NP_MSG_TIMEBASE = 0xB0,
NP_MSG_DESYNC_DETECTED = 0xB1, NP_MSG_DESYNC_DETECTED = 0xB1,

View File

@ -318,9 +318,14 @@ unsigned int NetPlayServer::OnConnect(ENetPeer* socket)
for (const auto& p : m_players) for (const auto& p : m_players)
{ {
spac.clear(); spac.clear();
spac << (MessageId)NP_MSG_PLAYER_JOIN; spac << static_cast<MessageId>(NP_MSG_PLAYER_JOIN);
spac << p.second.pid << p.second.name << p.second.revision; spac << p.second.pid << p.second.name << p.second.revision;
Send(player.socket, spac); Send(player.socket, spac);
spac.clear();
spac << static_cast<MessageId>(NP_MSG_GAME_STATUS);
spac << p.second.pid << static_cast<u32>(p.second.game_status);
Send(player.socket, spac);
} }
// add client to the player list // add client to the player list
@ -592,6 +597,23 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
} }
break; break;
case NP_MSG_GAME_STATUS:
{
u32 status;
packet >> status;
m_players[player.pid].game_status = static_cast<PlayerGameStatus>(status);
// send msg to other clients
sf::Packet spac;
spac << static_cast<MessageId>(NP_MSG_GAME_STATUS);
spac << player.pid;
spac << status;
SendToClients(spac);
}
break;
case NP_MSG_TIMEBASE: case NP_MSG_TIMEBASE:
{ {
u32 x, y, frame; u32 x, y, frame;

View File

@ -17,6 +17,8 @@
#include "Common/TraversalClient.h" #include "Common/TraversalClient.h"
#include "Core/NetPlayProto.h" #include "Core/NetPlayProto.h"
enum class PlayerGameStatus;
class NetPlayUI; class NetPlayUI;
class NetPlayServer : public TraversalClientClient class NetPlayServer : public TraversalClientClient
@ -64,6 +66,7 @@ private:
PlayerId pid; PlayerId pid;
std::string name; std::string name;
std::string revision; std::string revision;
PlayerGameStatus game_status;
ENetPeer* socket; ENetPeer* socket;
u32 ping; u32 ping;

View File

@ -288,19 +288,33 @@ void NetPlayDialog::GetNetSettings(NetSettings& settings)
settings.m_EXIDevice[1] = instance.m_EXIDevice[1]; settings.m_EXIDevice[1] = instance.m_EXIDevice[1];
} }
std::string NetPlayDialog::FindGame() std::string NetPlayDialog::FindGame(const std::string& target_game)
{ {
// find path for selected game, sloppy.. // find path for selected game, sloppy..
for (u32 i = 0; auto game = m_game_list->GetISO(i); ++i) for (u32 i = 0; auto game = m_game_list->GetISO(i); ++i)
if (m_selected_game == BuildGameName(*game)) if (target_game == BuildGameName(*game))
return game->GetFileName(); return game->GetFileName();
WxUtils::ShowErrorDialog(_("Game not found!"));
return ""; return "";
} }
std::string NetPlayDialog::FindCurrentGame()
{
return FindGame(m_selected_game);
}
void NetPlayDialog::OnStart(wxCommandEvent&) void NetPlayDialog::OnStart(wxCommandEvent&)
{ {
bool should_start = true;
if (!netplay_client->DoAllPlayersHaveGame())
{
should_start = wxMessageBox(_("Not all players have the game. Do you really want to start?"),
_("Warning"), wxYES_NO) == wxYES;
}
if (!should_start)
return;
NetSettings settings; NetSettings settings;
GetNetSettings(settings); GetNetSettings(settings);
netplay_server->SetNetSettings(settings); netplay_server->SetNetSettings(settings);
@ -442,7 +456,11 @@ void NetPlayDialog::OnThread(wxThreadEvent& event)
case NP_GUI_EVT_START_GAME: case NP_GUI_EVT_START_GAME:
// client start game :/ // client start game :/
{ {
netplay_client->StartGame(FindGame()); std::string game = FindCurrentGame();
if (game.empty())
WxUtils::ShowErrorDialog(_("Game not found!"));
else
netplay_client->StartGame(game);
} }
break; break;
case NP_GUI_EVT_STOP_GAME: case NP_GUI_EVT_STOP_GAME:

View File

@ -73,7 +73,8 @@ private:
void OnKick(wxCommandEvent& event); void OnKick(wxCommandEvent& event);
void OnPlayerSelect(wxCommandEvent& event); void OnPlayerSelect(wxCommandEvent& event);
void GetNetSettings(NetSettings& settings); void GetNetSettings(NetSettings& settings);
std::string FindGame(); std::string FindCurrentGame();
std::string FindGame(const std::string& game);
void OnCopyIP(wxCommandEvent&); void OnCopyIP(wxCommandEvent&);
void OnChoice(wxCommandEvent& event); void OnChoice(wxCommandEvent& event);