Improve netplay setup dialog UX
* Focus "Hash Code" / "IP address" text box by default in "Connect" * Focus game list in "Host" tab * RETURN keypress now host/join depending on selected tab * Remember last hosted game * Remove PanicAlertT: * Simply log message to netplay window * Remove them when they are useless * Show some netplay message in OSD * Chat messages * Pad buffer changes * Desync alerts * Stop the game consistently when another player disconnects / crashes * Prettify chat textbox * Log netplay ping to OSD Join scenario: * Copy netplay code * Open netplay * Paste code * Press enter Host scenario: * Open netplay * Go to host tab * Press enter
This commit is contained in:
1 parent
aa34e5e20e
commit
6a0fc4c438
13 files changed
+428
-178
No files matched your search
@@ -27,6 +27,8 @@
|
||||
#include "Core/Movie.h"
|
||||
#include "Core/NetPlayClient.h"
|
||||
#include "InputCommon/GCAdapter.h"
|
||||
#include "VideoCommon/OnScreenDisplay.h"
|
||||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
static std::mutex crit_netplay_client;
|
||||
static NetPlayClient* netplay_client = nullptr;
|
||||
@@ -351,6 +353,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
packet >> size;
|
||||
|
||||
m_target_buffer_size = size;
|
||||
m_dialog->OnPadBufferChanged(size);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -428,17 +431,10 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
break;
|
||||
|
||||
case NP_MSG_STOP_GAME:
|
||||
{
|
||||
m_dialog->OnMsgStopGame();
|
||||
}
|
||||
break;
|
||||
|
||||
case NP_MSG_DISABLE_GAME:
|
||||
{
|
||||
PanicAlertT("Other client disconnected while game is running!! NetPlay is disabled. You must "
|
||||
"manually stop the game.");
|
||||
m_is_running.store(false);
|
||||
NetPlay_Disable();
|
||||
StopGame();
|
||||
m_dialog->OnMsgStopGame();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -466,6 +462,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
packet >> player.ping;
|
||||
}
|
||||
|
||||
DisplayPlayersPing();
|
||||
m_dialog->Update();
|
||||
}
|
||||
break;
|
||||
@@ -476,18 +473,15 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||
u32 frame;
|
||||
packet >> pid_to_blame;
|
||||
packet >> frame;
|
||||
const char* blame_str = "";
|
||||
const char* blame_name = "";
|
||||
|
||||
std::string player = "??";
|
||||
std::lock_guard<std::recursive_mutex> lkp(m_crit.players);
|
||||
if (pid_to_blame != -1)
|
||||
{
|
||||
auto it = m_players.find(pid_to_blame);
|
||||
blame_str = " from player ";
|
||||
blame_name = it != m_players.end() ? it->second.name.c_str() : "??";
|
||||
if (it != m_players.end())
|
||||
player = it->second.name;
|
||||
}
|
||||
|
||||
m_dialog->AppendChat(StringFromFormat("/!\\ Possible desync detected%s%s on frame %u",
|
||||
blame_str, blame_name, frame));
|
||||
m_dialog->OnDesync(frame, player);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -571,6 +565,24 @@ void NetPlayClient::Send(sf::Packet& packet)
|
||||
enet_peer_send(m_server, 0, epac);
|
||||
}
|
||||
|
||||
void NetPlayClient::DisplayPlayersPing()
|
||||
{
|
||||
if (!g_ActiveConfig.bShowNetPlayPing)
|
||||
return;
|
||||
|
||||
OSD::AddTypedMessage(OSD::MessageType::NetPlayPing,
|
||||
StringFromFormat("Ping: %u", GetPlayersMaxPing()), OSD::Duration::SHORT,
|
||||
OSD::Color::CYAN);
|
||||
}
|
||||
|
||||
u32 NetPlayClient::GetPlayersMaxPing() const
|
||||
{
|
||||
return std::max_element(
|
||||
m_players.begin(), m_players.end(),
|
||||
[](const auto& a, const auto& b) { return a.second.ping < b.second.ping; })
|
||||
->second.ping;
|
||||
}
|
||||
|
||||
void NetPlayClient::Disconnect()
|
||||
{
|
||||
ENetEvent netEvent;
|
||||
@@ -636,13 +648,11 @@ void NetPlayClient::ThreadFunc()
|
||||
enet_packet_destroy(netEvent.packet);
|
||||
break;
|
||||
case ENET_EVENT_TYPE_DISCONNECT:
|
||||
m_is_running.store(false);
|
||||
NetPlay_Disable();
|
||||
m_dialog->AppendChat("< LOST CONNECTION TO SERVER >");
|
||||
PanicAlertT("Lost connection to server!");
|
||||
m_do_loop.store(false);
|
||||
m_dialog->OnConnectionLost();
|
||||
|
||||
if (m_is_running.load())
|
||||
StopGame();
|
||||
|
||||
netEvent.peer->data = nullptr;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -786,8 +796,6 @@ bool NetPlayClient::StartGame(const std::string& path)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dialog->AppendChat(" -- STARTING GAME -- ");
|
||||
|
||||
m_timebase_frame = 0;
|
||||
|
||||
m_is_running.store(true);
|
||||
@@ -895,6 +903,7 @@ void NetPlayClient::OnTraversalStateChanged()
|
||||
m_traversal_client->m_State == TraversalClient::Failure)
|
||||
{
|
||||
Disconnect();
|
||||
m_dialog->OnTraversalError(m_traversal_client->m_FailureReason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,8 +1089,6 @@ bool NetPlayClient::StopGame()
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dialog->AppendChat(" -- STOPPING GAME -- ");
|
||||
|
||||
m_is_running.store(false);
|
||||
NetPlay_Disable();
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@ public:
|
||||
virtual void OnMsgChangeGame(const std::string& filename) = 0;
|
||||
virtual void OnMsgStartGame() = 0;
|
||||
virtual void OnMsgStopGame() = 0;
|
||||
virtual void OnPadBufferChanged(u32 buffer) = 0;
|
||||
virtual void OnDesync(u32 frame, const std::string& player) = 0;
|
||||
virtual void OnConnectionLost() = 0;
|
||||
virtual void OnTraversalError(int error) = 0;
|
||||
virtual bool IsRecording() = 0;
|
||||
virtual std::string FindGame(const std::string& game) = 0;
|
||||
virtual void ShowMD5Dialog(const std::string& file_identifier) = 0;
|
||||
@@ -157,6 +161,8 @@ private:
|
||||
void Disconnect();
|
||||
bool Connect();
|
||||
void ComputeMD5(const std::string& file_identifier);
|
||||
void DisplayPlayersPing();
|
||||
u32 GetPlayersMaxPing() const;
|
||||
|
||||
bool m_is_connected = false;
|
||||
ConnectionState m_connection_state = ConnectionState::Failure;
|
||||
|
||||
@@ -350,15 +350,13 @@ unsigned int NetPlayServer::OnDisconnect(Client& player)
|
||||
{
|
||||
if (mapping == pid && pid != 1)
|
||||
{
|
||||
PanicAlertT("Client disconnect while game is running!! NetPlay is disabled. You must "
|
||||
"manually stop the game.");
|
||||
std::lock_guard<std::recursive_mutex> lkg(m_crit.game);
|
||||
m_is_running = false;
|
||||
|
||||
sf::Packet spac;
|
||||
spac << (MessageId)NP_MSG_DISABLE_GAME;
|
||||
// this thread doesn't need players lock
|
||||
SendToClients(spac, 1);
|
||||
SendToClients(spac, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -636,19 +634,15 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
|
||||
}))
|
||||
{
|
||||
int pid_to_blame = -1;
|
||||
if (timebases.size() > 2)
|
||||
for (auto pair : timebases)
|
||||
{
|
||||
for (auto pair : timebases)
|
||||
if (std::all_of(timebases.begin(), timebases.end(), [&](std::pair<PlayerId, u64> other) {
|
||||
return other.first == pair.first || other.second != pair.second;
|
||||
}))
|
||||
{
|
||||
if (std::all_of(timebases.begin(), timebases.end(),
|
||||
[&](std::pair<PlayerId, u64> other) {
|
||||
return other.first == pair.first || other.second != pair.second;
|
||||
}))
|
||||
{
|
||||
// we are the only outlier
|
||||
pid_to_blame = pair.first;
|
||||
break;
|
||||
}
|
||||
// we are the only outlier
|
||||
pid_to_blame = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,8 +714,8 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
|
||||
|
||||
void NetPlayServer::OnTraversalStateChanged()
|
||||
{
|
||||
if (m_dialog)
|
||||
m_dialog->Update();
|
||||
if (m_dialog && m_traversal_client->m_State == TraversalClient::Failure)
|
||||
m_dialog->OnTraversalError(m_traversal_client->m_FailureReason);
|
||||
}
|
||||
|
||||
// called from ---GUI--- thread
|
||||
|
||||
Reference in new issue
Block a user