From 27732f10f130102d39a3f08bb7842bb54653e1b7 Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Sun, 14 Sep 2025 10:25:52 +0200 Subject: [PATCH 1/2] Announce netplay player information to the lobby server This information is optional and merely informational. The lobby might ignore it (and it ignores it at the current version). --- network/netplay/netplay.h | 2 ++ network/netplay/netplay_frontend.c | 44 ++++++++++++++++++++++++++-- network/netplay/netplay_room_parse.c | 4 +++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index 3c1b90da776f..604576241f3d 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -72,6 +72,8 @@ struct netplay_room int port; int mitm_port; int host_method; + int player_count; + int spectator_count; char nickname[NETPLAY_NICK_LEN]; char frontend[NETPLAY_HOST_STR_LEN]; char corename[NETPLAY_HOST_STR_LEN]; diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 7d55f0a970db..6e7042cb90a2 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -8400,6 +8400,31 @@ static bool netplay_should_skip(netplay_t *netplay) netplay->self_mode >= NETPLAY_CONNECTION_CONNECTED; } +static size_t retrieve_client_count(netplay_t *netplay, + unsigned *players, unsigned *spectators) +{ + size_t i, r = 0; + + for (i = 0; i < netplay->connections_size; i++) + { + struct netplay_connection *connection = &netplay->connections[i]; + + /* We only want info from already connected clients. */ + if ( (connection->flags & NETPLAY_CONN_FLAG_ACTIVE) + && (connection->mode >= NETPLAY_CONNECTION_CONNECTED)) + { + r++; + if (connection->mode == NETPLAY_CONNECTION_SPECTATING) + (*spectators)++; + else if (connection->mode == NETPLAY_CONNECTION_PLAYING + || connection->mode == NETPLAY_CONNECTION_SLAVE) + (*players)++; + } + } + + return r; +} + bool init_netplay_deferred(const char *server, unsigned port, const char *mitm_session) { net_driver_state_t *net_st = &networking_driver_st; @@ -8600,6 +8625,8 @@ static void netplay_announce(netplay_t *netplay) int mitm_custom_port = 0; int is_mitm = 0; uint32_t content_crc = 0; + unsigned players = 0; + unsigned spectators = 0; net_driver_state_t *net_st = &networking_driver_st; struct netplay_room *host_room = &net_st->host_room; struct retro_system_info *system = &runloop_state_get_ptr()->system.info; @@ -8678,6 +8705,15 @@ static void netplay_announce(netplay_t *netplay) else net_http_urlencode(&mitm_custom_addr, ""); + /* Purely informational, should not be used to guess if a host is full. */ + retrieve_client_count(netplay, &players, &spectators); + + if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING) + spectators++; + if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING + || netplay->self_mode == NETPLAY_CONNECTION_SLAVE) + players++; + /* Estimated to a maximum of 3062 bytes. */ snprintf(buf, sizeof(buf), "username=%s&" @@ -8695,7 +8731,9 @@ static void netplay_announce(netplay_t *netplay) "subsystem_name=%s&" "mitm_session=%s&" "mitm_custom_addr=%s&" - "mitm_custom_port=%d", + "mitm_custom_port=%d&" + "player_count=%d&" + "spectator_count=%d", username, corename, coreversion, @@ -8711,7 +8749,9 @@ static void netplay_announce(netplay_t *netplay) subsystemname, mitm_session, mitm_custom_addr, - mitm_custom_port); + mitm_custom_port, + players, + spectators); if (task_push_http_post_transfer(FILE_PATH_LOBBY_LIBRETRO_URL "add", buf, true, NULL, netplay_announce_cb, NULL)) diff --git a/network/netplay/netplay_room_parse.c b/network/netplay/netplay_room_parse.c index 059d87c7aa4d..6f178fef3399 100644 --- a/network/netplay/netplay_room_parse.c +++ b/network/netplay/netplay_room_parse.c @@ -223,6 +223,10 @@ static bool netplay_json_object_member(void *ctx, const char *p_value, p_ctx->cur_member_bool = &net_st->rooms_data->cur->connectable; else if (string_is_equal(p_value, "is_retroarch")) p_ctx->cur_member_bool = &net_st->rooms_data->cur->is_retroarch; + else if (string_is_equal(p_value, "player_count")) + p_ctx->cur_member_int = &net_st->rooms_data->cur->player_count; + else if (string_is_equal(p_value, "spectator_count")) + p_ctx->cur_member_int = &net_st->rooms_data->cur->spectator_count; } } From dfb340be0f9f9b7111560213c4b6a8b645d056be Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Sun, 14 Sep 2025 12:05:58 +0200 Subject: [PATCH 2/2] Display lobby information on player/spectator counts --- intl/msg_hash_us.h | 8 ++++++++ menu/cbs/menu_cbs_sublabel.c | 13 +++++++++++-- msg_hash.h | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 1591ba20a5d4..00e16cf50c71 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -14213,6 +14213,14 @@ MSG_HASH( MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, "%.*s has joined with input devices %.*s" ) +MSG_HASH( + MSG_NETPLAY_PLAYERS_INFO, + "%d player(s)" + ) +MSG_HASH( + MSG_NETPLAY_SPECTATORS_INFO, + "%d player(s) (%d spectating)" + ) MSG_HASH( MSG_NETPLAY_NOT_RETROARCH, "A netplay connection attempt failed because the peer is not running RetroArch, or is running an old version of RetroArch." diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 201589e79f5d..aa54592681a2 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -1817,14 +1817,23 @@ static int action_bind_sublabel_netplay_room(file_list_t *list, if ( string_is_empty(room->subsystem_name) || string_is_equal_case_insensitive(room->subsystem_name, "N/A")) - snprintf(s + _len, len - _len, "(%08lX)", + _len += snprintf(s + _len, len - _len, "(%08lX)\n", (unsigned long)(unsigned)room->gamecrc); else { _len += strlcpy(s + _len, "(", len - _len); _len += strlcpy(s + _len, room->subsystem_name, len - _len); - strlcpy(s + _len, ")", len - _len); + _len += strlcpy(s + _len, ")\n", len - _len); } + + if (room->spectator_count > 0) + _len += snprintf(s + _len, len - _len, + msg_hash_to_str(MSG_NETPLAY_SPECTATORS_INFO), + room->player_count, room->spectator_count); + else if (room->player_count >= 0) + _len += snprintf(s + _len, len - _len, + msg_hash_to_str(MSG_NETPLAY_PLAYERS_INFO), + room->player_count); return 0; } diff --git a/msg_hash.h b/msg_hash.h index e210305dd9e8..9b68db031c81 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -208,6 +208,8 @@ enum msg_hash_enums MSG_NETPLAY_PLAYER_S_LEFT, MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N, MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S, + MSG_NETPLAY_PLAYERS_INFO, + MSG_NETPLAY_SPECTATORS_INFO, MSG_NETPLAY_NOT_RETROARCH, MSG_NETPLAY_OUT_OF_DATE, MSG_NETPLAY_DIFFERENT_VERSIONS,