Merge pull request #3858 from Aestek/feature/better-netplay-gamenotfound

Netplay: check if all players have the game before starting
This commit is contained in:
Pierre Bourdon 2016-07-11 10:06:00 +02:00 committed by GitHub
commit f57aec0525
7 changed files with 116 additions and 7 deletions

View File

@ -356,6 +356,33 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
// update gui
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;
@ -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_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);
}
@ -1143,6 +1189,14 @@ void NetPlayClient::SendTimeBase()
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
// called from ---CPU--- thread

View File

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

View File

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

View File

@ -318,9 +318,14 @@ unsigned int NetPlayServer::OnConnect(ENetPeer* socket)
for (const auto& p : m_players)
{
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;
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
@ -592,6 +597,23 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
}
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:
{
u32 x, y, frame;

View File

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

View File

@ -288,19 +288,33 @@ void NetPlayDialog::GetNetSettings(NetSettings& settings)
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..
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();
WxUtils::ShowErrorDialog(_("Game not found!"));
return "";
}
std::string NetPlayDialog::FindCurrentGame()
{
return FindGame(m_selected_game);
}
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;
GetNetSettings(settings);
netplay_server->SetNetSettings(settings);
@ -442,7 +456,11 @@ void NetPlayDialog::OnThread(wxThreadEvent& event)
case NP_GUI_EVT_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;
case NP_GUI_EVT_STOP_GAME:

View File

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