Updated error messages and fixed some stall-related disconnected-client

bugs.
This commit is contained in:
Gregor Richards 2016-12-15 17:20:04 -05:00
parent 6658826759
commit 6890456ac0
14 changed files with 181 additions and 64 deletions

View File

@ -3543,8 +3543,6 @@ const char *msg_hash_to_str_chs(enum msg_hash_enums msg)
return "Stopping movie record.";
case MSG_NETPLAY_FAILED:
return "Failed to initialize netplay.";
case MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED:
return "Movie playback has started. Cannot start netplay.";
case MSG_NO_CONTENT_STARTING_DUMMY_CORE:
return "No content, starting dummy core.";
case MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET:

View File

@ -1962,8 +1962,6 @@ MSG_HASH(MSG_MOVIE_RECORD_STOPPED,
"Stopping movie record.")
MSG_HASH(MSG_NETPLAY_FAILED,
"Failed to initialize netplay.")
MSG_HASH(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
"Movie playback has started. Cannot start netplay.")
MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE,
"No content, starting dummy core.")
MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET,

View File

@ -1418,8 +1418,6 @@ const char *msg_hash_to_str_es(enum msg_hash_enums msg)
return "Deteniendo grabación de vídeo.";
case MSG_NETPLAY_FAILED:
return "Error al iniciar el juego en red.";
case MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED:
return "Se ha iniciado una reproducción. No se puede ejecutar el juego en red.";
case MSG_PAUSED:
return "En pausa.";
case MSG_PROGRAM:

View File

@ -1928,8 +1928,6 @@ MSG_HASH(MSG_MOVIE_RECORD_STOPPED,
"Arrêt de l'enregistrement vidéo.")
MSG_HASH(MSG_NETPLAY_FAILED,
"Échec de l'initialisation du jeu en réseau")
MSG_HASH(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
"Lecture en cours. Impossible d'activer le jeu en réseau.")
MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE,
"No content, starting dummy core.")
MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET,

View File

@ -1997,8 +1997,6 @@ MSG_HASH(MSG_MOVIE_RECORD_STOPPED,
"Stopping movie record.")
MSG_HASH(MSG_NETPLAY_FAILED,
"Failed to initialize netplay.")
MSG_HASH(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
"Movie playback has started. Cannot start netplay.")
MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE,
"No content, starting dummy core.")
MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET,

View File

@ -1962,8 +1962,6 @@ MSG_HASH(MSG_MOVIE_RECORD_STOPPED,
"Stopping movie record.")
MSG_HASH(MSG_NETPLAY_FAILED,
"Failed to initialize netplay.")
MSG_HASH(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
"Movie playback has started. Cannot start netplay.")
MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE,
"No content, starting dummy core.")
MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET,

View File

@ -925,8 +925,6 @@ const char *msg_hash_to_str_pl(enum msg_hash_enums msg)
return "Zatrzymano nagrywanie filmu.";
case MSG_NETPLAY_FAILED:
return "Nie udało się zainicjalizować gry sieciowej.";
case MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED:
return "Odtwarzanie filmu w toku. Nie można rozpocząć gry sieciowej.";
case MSG_PAUSED:
return "Wstrzymano.";
case MSG_PROGRAM:

View File

@ -1961,8 +1961,6 @@ MSG_HASH(MSG_MOVIE_RECORD_STOPPED,
"Запись остановлена.")
MSG_HASH(MSG_NETPLAY_FAILED,
"Ошибка запуска сетевой игры.")
MSG_HASH(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
"Воспроизведение записи. Невозможно начать сетевую игру.")
MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE,
"No content, starting dummy core.")
MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET,

View File

@ -46,6 +46,58 @@ MSG_HASH(
MSG_WAITING_FOR_CLIENT,
"Waiting for client ..."
)
MSG_HASH(
MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME,
"You have left the game."
)
MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"You have joined as player %d."
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Implementations differ. Make sure you're using the exact same versions of RetroArch and the core."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"This core does not support inter-architecture netplay between these systems."
)
MSG_HASH(
MSG_NETPLAY_PLATFORM_DEPENDENT,
"This core does not support inter-architecture netplay."
)
MSG_HASH(
MSG_NETPLAY_ENTER_PASSWORD,
"Enter netplay server password:"
)
MSG_HASH(
MSG_NETPLAY_INCORRECT_PASSWORD,
"Incorrect password."
)
MSG_HASH(
MSG_NETPLAY_SERVER_NAMED_HANGUP,
"\"%s\" has disconnected."
)
MSG_HASH(
MSG_NETPLAY_SERVER_HANGUP,
"A netplay client has disconnected."
)
MSG_HASH(
MSG_NETPLAY_CLIENT_HANGUP,
"Netplay disconnected."
)
MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED,
"You do not have permission to play."
)
MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS,
"There are no free player slots."
)
MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY,
"Cannot switch to play mode."
)
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."
@ -1992,8 +2044,6 @@ MSG_HASH(MSG_MOVIE_RECORD_STOPPED,
"Stopping movie record.")
MSG_HASH(MSG_NETPLAY_FAILED,
"Failed to initialize netplay.")
MSG_HASH(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
"Movie playback has started. Cannot start netplay.")
MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE,
"No content, starting dummy core.")
MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET,

View File

@ -3591,8 +3591,6 @@ const char *msg_hash_to_str_vn(enum msg_hash_enums msg)
return "Stopping movie record.";
case MSG_NETPLAY_FAILED:
return "Failed to initialize netplay.";
case MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED:
return "Movie playback has started. Cannot start netplay.";
case MSG_NO_CONTENT_STARTING_DUMMY_CORE:
return "No content, starting dummy core.";
case MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET:

View File

@ -140,12 +140,26 @@ enum msg_hash_enums
MSG_UNKNOWN = 0,
MSG_SETTING_DISK_IN_TRAY,
MSG_FAILED_TO_SET_DISK,
MSG_NETPLAY_FAILED,
MSG_NETPLAY_USERS_HAS_FLIPPED,
MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED,
MSG_CONNECTING_TO_NETPLAY_HOST,
MSG_NETPLAY_LAN_SCAN_COMPLETE,
MSG_NETPLAY_LAN_SCANNING,
MSG_WAITING_FOR_CLIENT,
MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME,
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
MSG_NETPLAY_ENDIAN_DEPENDENT,
MSG_NETPLAY_PLATFORM_DEPENDENT,
MSG_NETPLAY_ENTER_PASSWORD,
MSG_NETPLAY_INCORRECT_PASSWORD,
MSG_NETPLAY_SERVER_NAMED_HANGUP,
MSG_NETPLAY_SERVER_HANGUP,
MSG_NETPLAY_CLIENT_HANGUP,
MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED,
MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS,
MSG_NETPLAY_CANNOT_PLAY,
MSG_AUTODETECT,
MSG_AUDIO_VOLUME,
MSG_LIBRETRO_FRONTEND,
@ -273,8 +287,6 @@ enum msg_hash_enums
MSG_REWIND_INIT_FAILED,
MSG_REWIND_INIT_FAILED_THREADED_AUDIO,
MSG_LIBRETRO_ABI_BREAK,
MSG_NETPLAY_FAILED,
MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED,
MSG_DETECTED_VIEWPORT_OF,
MSG_RECORDING_TO,
MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING,

View File

@ -172,6 +172,10 @@ static bool netplay_poll(void)
get_self_input_state(netplay_data);
/* If we're not connected, we're done */
if (netplay_data->self_mode == NETPLAY_CONNECTION_NONE)
return true;
/* Read Netplay input, block if we're configured to stall for input every
* frame */
if (netplay_data->delay_frames == 0 &&
@ -682,6 +686,7 @@ static void netplay_toggle_play_spectate(netplay_t *netplay)
/* FIXME: Duplication */
uint32_t payload[2];
char msg[512];
const char *dmsg;
payload[0] = htonl(netplay->self_frame_count);
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING)
{
@ -689,9 +694,7 @@ static void netplay_toggle_play_spectate(netplay_t *netplay)
payload[1] = htonl(netplay->self_player);
netplay->self_mode = NETPLAY_CONNECTION_SPECTATING;
strlcpy(msg, "You have left the game", sizeof(msg));
RARCH_LOG("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
dmsg = msg_hash_to_str(MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME);
}
else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING)
@ -707,12 +710,14 @@ static void netplay_toggle_play_spectate(netplay_t *netplay)
netplay->self_mode = NETPLAY_CONNECTION_PLAYING;
netplay->self_player = player;
dmsg = msg;
msg[sizeof(msg)-1] = '\0';
snprintf(msg, sizeof(msg)-1, "You have joined as player %d", player+1);
RARCH_LOG("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
snprintf(msg, sizeof(msg)-1, msg_hash_to_str(MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N), player+1);
}
RARCH_LOG("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
netplay_send_raw_cmd_all(netplay, NULL, NETPLAY_CMD_MODE, payload, sizeof(payload));
}
@ -788,16 +793,6 @@ bool init_netplay(void *direct_host, const char *server, unsigned port,
if (!netplay_enabled)
return false;
#if 0
/* FIXME: This may still be relevant? */
if (bsv_movie_ctl(BSV_MOVIE_CTL_START_PLAYBACK, NULL))
{
RARCH_WARN("%s\n",
msg_hash_to_str(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED));
return false;
}
#endif
core_set_default_callbacks(&cbs);
/* Map the core's quirks to our quirks */

View File

@ -324,31 +324,30 @@ bool netplay_handshake_init(netplay_t *netplay,
{
uint32_t header[5] = {0};
ssize_t recvd;
char msg[512];
const char *dmsg;
struct nick_buf_s nick_buf;
uint32_t *content_crc_ptr = NULL;
uint32_t local_pmagic, remote_pmagic;
uint32_t compression;
msg[0] = '\0';
dmsg = NULL;
RECV(header, sizeof(header))
{
strlcpy(msg, msg_hash_to_str(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT), sizeof(msg));
dmsg = msg_hash_to_str(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT);
goto error;
}
if (netplay_impl_magic() != ntohl(header[0]))
{
strlcpy(msg, "Implementations differ. Make sure you're using exact same "
"libretro implementations and RetroArch version.", sizeof(msg));
dmsg = msg_hash_to_str(MSG_NETPLAY_IMPLEMENTATIONS_DIFFER);
goto error;
}
content_get_crc(&content_crc_ptr);
if (*content_crc_ptr != ntohl(header[1]))
{
strlcpy(msg, msg_hash_to_str(MSG_CONTENT_CRC32S_DIFFER), sizeof(msg));
dmsg = msg_hash_to_str(MSG_CONTENT_CRC32S_DIFFER);
goto error;
}
@ -359,16 +358,14 @@ bool netplay_handshake_init(netplay_t *netplay,
netplay_endian_mismatch(local_pmagic, remote_pmagic))
{
RARCH_ERR("Endianness mismatch with an endian-sensitive core.\n");
strlcpy(msg, "This core does not support inter-architecture netplay "
"between these systems.", sizeof(msg));
dmsg = msg_hash_to_str(MSG_NETPLAY_ENDIAN_DEPENDENT);
goto error;
}
if ((netplay->quirks & NETPLAY_QUIRK_PLATFORM_DEPENDENT) &&
(local_pmagic != remote_pmagic))
{
RARCH_ERR("Platform mismatch with a platform-sensitive core.\n");
strlcpy(msg, "This core does not support inter-architecture netplay.",
sizeof(msg));
dmsg = msg_hash_to_str(MSG_NETPLAY_PLATFORM_DEPENDENT);
goto error;
}
@ -409,7 +406,7 @@ bool netplay_handshake_init(netplay_t *netplay,
rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
memset(&line, 0, sizeof(line));
handshake_password_netplay = netplay;
line.label = "Enter Netplay server password:";
line.label = msg_hash_to_str(MSG_NETPLAY_ENTER_PASSWORD);
line.label_setting = "no_setting";
line.cb = handshake_password;
menu_input_dialog_start(&line);
@ -432,10 +429,10 @@ bool netplay_handshake_init(netplay_t *netplay,
return true;
error:
if (msg[0])
if (dmsg)
{
RARCH_ERR("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
RARCH_ERR("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
}
return false;
}
@ -678,7 +675,7 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
RECV(cmd, sizeof(cmd))
{
char *msg = "Incorrect password.";
const char *msg = msg_hash_to_str(MSG_NETPLAY_INCORRECT_PASSWORD);
RARCH_ERR("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
return false;

View File

@ -57,13 +57,31 @@ static void remote_unpaused(netplay_t *netplay, struct netplay_connection *conne
*/
void netplay_hangup(netplay_t *netplay, struct netplay_connection *connection)
{
char msg[512];
const char *dmsg;
if (!netplay)
return;
if (!connection->active)
return;
RARCH_WARN("Netplay has disconnected. Will continue without connection ...\n");
runloop_msg_queue_push("Netplay has disconnected. Will continue without connection.", 0, 480, false);
msg[0] = msg[sizeof(msg)-1] = '\0';
dmsg = msg;
/* Report this disconnection */
if (netplay->is_server)
{
if (connection->nick[0])
snprintf(msg, sizeof(msg)-1, msg_hash_to_str(MSG_NETPLAY_SERVER_NAMED_HANGUP), connection->nick);
else
dmsg = msg_hash_to_str(MSG_NETPLAY_SERVER_HANGUP);
}
else
{
dmsg = msg_hash_to_str(MSG_NETPLAY_CLIENT_HANGUP);
}
RARCH_LOG("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
socket_close(connection->fd);
connection->active = false;
@ -74,6 +92,7 @@ void netplay_hangup(netplay_t *netplay, struct netplay_connection *connection)
{
netplay->self_mode = NETPLAY_CONNECTION_NONE;
netplay->connected_players = 0;
netplay->stall = NETPLAY_STALL_NONE;
}
else
@ -431,7 +450,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
{
/* Ignore the claimed player #, must be this client */
if (connection->mode != NETPLAY_CONNECTION_PLAYING)
{
RARCH_ERR("Netplay input from non-participating player.\n");
return netplay_cmd_nak(netplay, connection);
}
player = connection->player;
}
else
@ -440,7 +462,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
}
if (player >= MAX_USERS || !(netplay->connected_players & (1<<player)))
{
RARCH_ERR("Invalid NETPLAY_CMD_INPUT player number.\n");
return netplay_cmd_nak(netplay, connection);
}
if (buffer[0] < netplay->read_frame_count[player])
{
@ -450,6 +475,7 @@ static bool netplay_get_cmd(netplay_t *netplay,
else if (buffer[0] > netplay->read_frame_count[player])
{
/* Out of order = out of luck */
RARCH_ERR("Netplay input out of order.\n");
return netplay_cmd_nak(netplay, connection);
}
@ -458,6 +484,7 @@ static bool netplay_get_cmd(netplay_t *netplay,
if (!netplay_delta_frame_ready(netplay, dframe, netplay->read_frame_count[player]))
{
/* FIXME: Catastrophe! */
RARCH_ERR("Netplay input without a ready delta frame!\n");
return netplay_cmd_nak(netplay, connection);
}
memcpy(dframe->real_input_state[player], buffer + 2,
@ -488,14 +515,23 @@ static bool netplay_get_cmd(netplay_t *netplay,
uint32_t frame;
if (netplay->is_server)
{
RARCH_ERR("NETPLAY_CMD_NOINPUT from a client.\n");
return netplay_cmd_nak(netplay, connection);
}
RECV(&frame, sizeof(frame))
{
RARCH_ERR("Failed to receive NETPLAY_CMD_NOINPUT payload.\n");
return netplay_cmd_nak(netplay, connection);
}
frame = ntohl(frame);
if (frame != netplay->server_frame_count)
{
RARCH_ERR("NETPLAY_CMD_NOINPUT for invalid frame.\n");
return netplay_cmd_nak(netplay, connection);
}
netplay->server_ptr = NEXT_PTR(netplay->server_ptr);
netplay->server_frame_count++;
@ -516,7 +552,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
}
if (netplay->is_server)
{
RARCH_ERR("NETPLAY_CMD_FLIP_PLAYERS from a client.\n");
return netplay_cmd_nak(netplay, connection);
}
flip_frame = ntohl(flip_frame);
@ -546,7 +585,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
uint32_t payload[2];
if (!netplay->is_server)
{
RARCH_ERR("NETPLAY_CMD_SPECTATE from a server.\n");
return netplay_cmd_nak(netplay, connection);
}
if (connection->mode == NETPLAY_CONNECTION_PLAYING)
{
@ -585,7 +627,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
payload[0] = htonl(netplay->self_frame_count + 1);
if (!netplay->is_server)
{
RARCH_ERR("NETPLAY_CMD_PLAY from a server.\n");
return netplay_cmd_nak(netplay, connection);
}
if (!connection->can_play)
{
@ -661,7 +706,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
if (cmd_size != sizeof(payload) ||
netplay->is_server)
{
RARCH_ERR("Invalid payload size for NETPLAY_CMD_MODE.\n");
return netplay_cmd_nak(netplay, connection);
}
RECV(payload, sizeof(payload))
{
@ -669,9 +717,6 @@ static bool netplay_get_cmd(netplay_t *netplay,
return netplay_cmd_nak(netplay, connection);
}
if (netplay->is_server)
return netplay_cmd_nak(netplay, connection);
frame = ntohl(payload[0]);
/* We're changing past input, so must replay it */
@ -681,7 +726,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
mode = ntohl(payload[1]);
player = mode & 0xFFFF;
if (player >= MAX_USERS)
{
RARCH_ERR("Received NETPLAY_CMD_MODE for a higher player number than we support.\n");
return netplay_cmd_nak(netplay, connection);
}
if (mode & NETPLAY_CMD_MODE_BIT_YOU)
{
@ -689,11 +737,17 @@ static bool netplay_get_cmd(netplay_t *netplay,
if (mode & NETPLAY_CMD_MODE_BIT_PLAYING)
{
if (frame != netplay->server_frame_count)
{
RARCH_ERR("Received mode change out of order.\n");
return netplay_cmd_nak(netplay, connection);
}
/* Hooray, I get to play now! */
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING)
{
RARCH_ERR("Received player mode change even though I'm already a player.\n");
return netplay_cmd_nak(netplay, connection);
}
netplay->self_mode = NETPLAY_CONNECTION_PLAYING;
netplay->self_player = player;
@ -738,7 +792,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
{
/* I'm no longer playing, but I should already know this */
if (netplay->self_mode != NETPLAY_CONNECTION_SPECTATING)
{
RARCH_ERR("Received mode change to spectator unprompted.\n");
return netplay_cmd_nak(netplay, connection);
}
/* Announce it */
strlcpy(msg, "You have left the game", sizeof(msg));
@ -754,7 +811,10 @@ static bool netplay_get_cmd(netplay_t *netplay,
if (mode & NETPLAY_CMD_MODE_BIT_PLAYING)
{
if (frame != netplay->server_frame_count)
{
RARCH_ERR("Received mode change out of order.\n");
return netplay_cmd_nak(netplay, connection);
}
netplay->connected_players |= (1<<player);
@ -790,31 +850,46 @@ static bool netplay_get_cmd(netplay_t *netplay,
case NETPLAY_CMD_MODE_REFUSED:
{
uint32_t reason;
char msg[512];
const char *dmsg = NULL;
if (netplay->is_server)
{
RARCH_ERR("NETPLAY_CMD_MODE_REFUSED from client.\n");
return netplay_cmd_nak(netplay, connection);
}
if (cmd_size != sizeof(uint32_t))
{
RARCH_ERR("Received invalid payload size for NETPLAY_CMD_MODE_REFUSED.\n");
return netplay_cmd_nak(netplay, connection);
}
RECV(&reason, sizeof(reason))
{
RARCH_ERR("Failed to receive NETPLAY_CMD_MODE_REFUSED payload.\n");
return netplay_cmd_nak(netplay, connection);
}
reason = ntohl(reason);
switch (reason)
{
case NETPLAY_CMD_MODE_REFUSED_REASON_UNPRIVILEGED:
strlcpy(msg, "You do not have permission to play.", sizeof(msg));
dmsg = msg_hash_to_str(MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED);
break;
case NETPLAY_CMD_MODE_REFUSED_REASON_NO_SLOTS:
strlcpy(msg, "There are no free player slots.", sizeof(msg));
dmsg = msg_hash_to_str(MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS);
break;
default:
strlcpy(msg, "Cannot switch to play mode.", sizeof(msg));
dmsg = msg_hash_to_str(MSG_NETPLAY_CANNOT_PLAY);
}
RARCH_LOG("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
if (dmsg)
{
RARCH_LOG("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
}
break;
}
@ -918,12 +993,18 @@ static bool netplay_get_cmd(netplay_t *netplay,
/* Only players may load states */
if (connection->mode != NETPLAY_CONNECTION_PLAYING)
{
RARCH_ERR("Netplay state load from a spectator.\n");
return netplay_cmd_nak(netplay, connection);
}
/* We only allow players to load state if we're in a simple
* two-player situation */
if (netplay->is_server && netplay->connections_size > 1)
{
RARCH_ERR("Netplay state load from a client with other clients connected disallowed.\n");
return netplay_cmd_nak(netplay, connection);
}
/* There is a subtlty in whether the load comes before or after the
* current frame: