diff --git a/intl/msg_hash_chs.c b/intl/msg_hash_chs.c index d0af2f7528..5afbaa8a9e 100644 --- a/intl/msg_hash_chs.c +++ b/intl/msg_hash_chs.c @@ -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: diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 9d02ebdb47..192e07cdef 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -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, diff --git a/intl/msg_hash_es.c b/intl/msg_hash_es.c index c1ca78b1ed..24af507256 100644 --- a/intl/msg_hash_es.c +++ b/intl/msg_hash_es.c @@ -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: diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 5bfa10339b..9b1eb68d15 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -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, diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index db08136d9d..14fc3b3dfc 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -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, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 29b22cf2b7..aec4814f3f 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -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, diff --git a/intl/msg_hash_pl.c b/intl/msg_hash_pl.c index 6a25406182..dc708fa921 100644 --- a/intl/msg_hash_pl.c +++ b/intl/msg_hash_pl.c @@ -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: diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 7d67b620a8..e181db67e1 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -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, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index af1e9544aa..2b263696ed 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -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, diff --git a/intl/msg_hash_vn.c b/intl/msg_hash_vn.c index bf101e0281..410367850c 100644 --- a/intl/msg_hash_vn.c +++ b/intl/msg_hash_vn.c @@ -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: diff --git a/msg_hash.h b/msg_hash.h index 7793fd026c..ab8d972ae9 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -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, diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 8c43f59b2a..ab75f96735 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -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 */ diff --git a/network/netplay/netplay_handshake.c b/network/netplay/netplay_handshake.c index e2b65d1454..337dc033bf 100644 --- a/network/netplay/netplay_handshake.c +++ b/network/netplay/netplay_handshake.c @@ -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; diff --git a/network/netplay/netplay_io.c b/network/netplay/netplay_io.c index 9db7631e3f..781f2f5b13 100644 --- a/network/netplay/netplay_io.c +++ b/network/netplay/netplay_io.c @@ -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<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<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: