Improvements to the communication of netplay pausing.

This commit is contained in:
Gregor Richards 2016-12-16 19:54:50 -05:00
parent db2c8de44c
commit 1fa60b396f
5 changed files with 71 additions and 10 deletions

View File

@ -98,6 +98,10 @@ MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY,
"Cannot switch to play mode."
)
MSG_HASH(
MSG_NETPLAY_PEER_PAUSED,
"Netplay peer \"%s\" paused."
)
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT,
"Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames."

View File

@ -160,6 +160,7 @@ enum msg_hash_enums
MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED,
MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS,
MSG_NETPLAY_CANNOT_PLAY,
MSG_NETPLAY_PEER_PAUSED,
MSG_AUTODETECT,
MSG_AUDIO_VOLUME,
MSG_LIBRETRO_FRONTEND,

View File

@ -255,11 +255,18 @@ Description:
serialized state is zlib compressed. Otherwise it is uncompressed.
Command: PAUSE
Payload: None
Payload:
{
nickname: char[32]
}
Description:
Indicates that the core is paused. The receiving peer should also pause.
The server should pass it on, using the known correct name rather than the
provided name.
Command: RESUME
Payload: None
Description:
Indicates that the core is no longer paused.
Command: CHEATS

View File

@ -467,6 +467,7 @@ static void netplay_flip_users(netplay_t *netplay)
static void netplay_frontend_paused(netplay_t *netplay, bool paused)
{
size_t i;
uint32_t paused_ct;
/* Nothing to do if we already knew this */
if (netplay->local_paused == paused)
@ -474,18 +475,33 @@ static void netplay_frontend_paused(netplay_t *netplay, bool paused)
netplay->local_paused = paused;
/* If other connections are paused, nothing to say */
if (netplay->remote_paused)
/* Communicating this is a bit odd: If exactly one other connection is
* paused, then we must tell them that we're unpaused, as from their
* perspective we are. If more than one other connection is paused, then our
* status as proxy means we are NOT unpaused to either of them. */
paused_ct = 0;
for (i = 0; i < netplay->connections_size; i++)
{
struct netplay_connection *connection = &netplay->connections[i];
if (connection->active && connection->paused)
paused_ct++;
}
if (paused_ct > 1)
return;
/* Have to send manually because every buffer must be flushed immediately */
/* Send our unpaused status. Must send manually because we must immediately
* flush the buffer: If we're paused, we won't be polled. */
for (i = 0; i < netplay->connections_size; i++)
{
struct netplay_connection *connection = &netplay->connections[i];
if (connection->active && connection->mode >= NETPLAY_CONNECTION_CONNECTED)
{
netplay_send_raw_cmd(netplay, connection,
paused ? NETPLAY_CMD_PAUSE : NETPLAY_CMD_RESUME, NULL, 0);
if (paused)
netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_PAUSE,
netplay->nick, NETPLAY_NICK_LEN);
else
netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_RESUME,
NULL, 0);
/* We're not going to be polled, so we need to flush this command now */
netplay_send_flush(&connection->send_packet_buffer, connection->fd, true);

View File

@ -1095,10 +1095,43 @@ static bool netplay_get_cmd(netplay_t *netplay,
}
case NETPLAY_CMD_PAUSE:
connection->paused = true;
netplay->remote_paused = true;
netplay_send_raw_cmd_all(netplay, connection, NETPLAY_CMD_PAUSE, NULL, 0);
break;
{
char msg[512], nick[NETPLAY_NICK_LEN];
msg[sizeof(msg)-1] = '\0';
/* Read in the paused nick */
if (cmd_size != sizeof(nick))
{
RARCH_ERR("NETPLAY_CMD_PAUSE received invalid payload size.\n");
return netplay_cmd_nak(netplay, connection);
}
RECV(nick, sizeof(nick))
{
RARCH_ERR("Failed to receive paused nickname.\n");
return netplay_cmd_nak(netplay, connection);
}
nick[sizeof(nick)-1] = '\0';
/* We outright ignore pausing from spectators */
if (connection->mode != NETPLAY_CONNECTION_PLAYING)
break;
connection->paused = true;
netplay->remote_paused = true;
if (netplay->is_server)
{
snprintf(msg, sizeof(msg)-1, msg_hash_to_str(MSG_NETPLAY_PEER_PAUSED), connection->nick);
netplay_send_raw_cmd_all(netplay, connection, NETPLAY_CMD_PAUSE,
connection->nick, NETPLAY_NICK_LEN);
}
else
{
snprintf(msg, sizeof(msg)-1, msg_hash_to_str(MSG_NETPLAY_PEER_PAUSED), nick);
}
RARCH_LOG("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
break;
}
case NETPLAY_CMD_RESUME:
remote_unpaused(netplay, connection);