Netplay Stuff (#13375)

* Netplay Stuff

## PROTOCOL FALLBACK
In order to support older clients a protocol fallback system was introduced.
The host will no longer send its header automatically after a TCP connection is established, instead, it awaits for the client to send his before determining which protocol this connection is going to operate on.
Netplay has now two protocols, a low protocol and a high protocol; the low protocol is the minimum protocol it supports, while the high protocol is the highest protocol it can operate on.
To fully support older clients, a hack was necessary: sending the high protocol in the unused client's header salt field, while keeping the protocol field to the low protocol. Without this hack we would only be able to support older clients if a newer client was the host.
Any future system can make use of this system by checking connection->netplay_protocol, which is available for both the client and host.

## NETPLAY CHAT
Starting with protocol 6, netplay chat is available through the new NETPLAY_CMD_PLAYER_CHAT command.
Limitations of the command code, which causes a disconnection on unknown commands, makes this system not possible on protocol 5.
Protocol 5 connections can neither send nor receive chat, but other netplay operations are unaffected.
Clients send chat as a string to the server, and it's the server's sole responsability to relay chat messages.
As of now, sending chat uses RetroArch's input menu, while the display of on-screen chat uses a widget overlay and RetroArch's notifications as a fallback.
If a new overlay and/or input system is desired, no backwards compatibility changes need to be made.
Only clients in playing mode (as opposed to spectating mode) can send and receive chat.

## SETTINGS SHARING
Some settings are better used when both host and clients share the same configuration.
As of protocol 6, the following settings will be shared from host to clients (without altering a client's configuration file): input latency frames and allow pausing.

## NETPLAY TUNNEL/MITM
With the current MITM system being defunct (at least as of 1.9.X), a new system was in order to solve most if not all of the problems with the current system.
This new system uses a tunneling approach, which is similar to most VPN and tunneling services around.

Tunnel commands:
RATS[unique id] (RetroArch Tunnel Session) - 16 bytes -> When this command is sent with a zeroed unique id, the tunnel server interprets this as a netplay host wanting to create a new session, in this case, the same command is returned to the host, but now with its unique session id. When a client needs to connect to a host, this command is sent with the unique session id of the host, causing the tunnel server to send a RATL command to the host.
RATL[unique id] (RetroArch Tunnel Link) - 16 bytes -> The tunnel server sends this command to the host when a client wants to connect to the host. Once the host receives this command, it establishes a new connection to the tunnel server, sending this command together with the client's unique id through this new connection, causing the tunnel server to link this connection to the connection of the client.
RATP (RetroArch Tunnel Ping) - 4 bytes -> The tunnel server sends this command to verify that the host, whom the session belongs to, is still around. The host replies with the same command. A session is closed if the tunnel server can not verify that the host is alive.

Operations:
Host -> Instead of listening and accepting connections, it connects to the tunnel server, requests a new session and then monitor this connection for new linking requests. Once a request is received, it establishes a new connection to the tunnel server for linking with a client. The tunnel server's address and port are obtained by querying the lobby server. The host will publish its session id together with the rest of its info to the lobby server.
Client -> It connects to the tunnel server and then sends the session id of the host it wants to connect to. A host's session id is obtained from the json data sent by the lobby server.

Improvements (from current MITM system):
No longer a risk of TCP port exhaustion; we only use one port now at the tunnel server.
Very little cpu usage. About 95% net I/O bound now.
Future backwards compatible with any and all changes to netplay as it no longer runs any netplay logic at MITM servers.
No longer operates the host in client mode, which was a source of many of the current problems.
Cleaner and more maintainable system and code.

Notable functions:
netplay_mitm_query -> Grabs the tunnel's address and port from the lobby server.
init_tcp_socket -> Handles the creation and operation mode of the TCP socket based on whether it's host, host+MITM or client.
handle_mitm_connection -> Creates and completes linking connections and replies to ping commands (only 1 of each per call to not affect performance).

## MISC
Ping Limiter: If a client's estimated latency to the server is higher than this value, connection will be dropped just before finishing the netplay handshake.
Ping Counter: A ping counter (similar to the FPS one) can be shown in the bottom right corner of the screen, if you are connected to a host.
LAN Discovery: Refactored and moved to its own "Refresh Netplay LAN List" button.

## FIXES
Many minor fixes to the current netplay implementation are also included.

* Remove NETPLAY_TEST_BUILD
This commit is contained in:
Cthulhu-throwaway 2021-12-19 12:58:01 -03:00 committed by GitHub
parent b7c14f61bc
commit 690c802921
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 3091 additions and 1439 deletions

View File

@ -45,6 +45,10 @@
#include "../menu/menu_driver.h"
#endif
#ifdef HAVE_NETWORKING
#include "../network/netplay/netplay.h"
#endif
#include "../configuration.h"
#include "../driver.h"
#include "../frontend/frontend_driver.h"
@ -1604,7 +1608,14 @@ bool audio_driver_callback(void)
settings_t *settings = config_get_ptr();
bool runloop_paused = runloop_state_get_ptr()->paused;
#ifdef HAVE_MENU
bool core_paused = runloop_paused || (settings->bools.menu_pause_libretro && menu_state_get_ptr()->alive);
#ifdef HAVE_NETWORKING
bool core_paused = runloop_paused ||
(settings->bools.menu_pause_libretro && menu_state_get_ptr()->alive &&
netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL));
#else
bool core_paused = runloop_paused ||
(settings->bools.menu_pause_libretro && menu_state_get_ptr()->alive);
#endif
#else
bool core_paused = runloop_paused;
#endif

View File

@ -119,6 +119,8 @@ enum event_command
CMD_EVENT_AUDIO_MUTE_TOGGLE,
/* Toggles FPS counter. */
CMD_EVENT_FPS_TOGGLE,
/* Toggle ping counter. */
CMD_EVENT_NETPLAY_PING_TOGGLE,
/* Gathers diagnostic info about the system and RetroArch configuration, then sends it to our servers. */
CMD_EVENT_SEND_DEBUG_INFO,
/* Toggles netplay hosting. */
@ -202,6 +204,10 @@ enum event_command
CMD_EVENT_NETPLAY_DEINIT,
/* Switch between netplay gaming and watching. */
CMD_EVENT_NETPLAY_GAME_WATCH,
/* Open a netplay chat input menu. */
CMD_EVENT_NETPLAY_PLAYER_CHAT,
/* Toggle chat fading. */
CMD_EVENT_NETPLAY_FADE_CHAT_TOGGLE,
/* Start hosting netplay. */
CMD_EVENT_NETPLAY_ENABLE_HOST,
/* Disconnect from the netplay host. */

View File

@ -1110,6 +1110,9 @@ static const bool audio_enable_menu_bgm = false;
/* Enables displaying various timing statistics. */
#define DEFAULT_STATISTICS_SHOW false
/* Enables displaying the current netplay room ping. */
#define DEFAULT_NETPLAY_PING_SHOW false
/* Enables use of rewind. This will incur some memory footprint
* depending on the save state buffer. */
#define DEFAULT_REWIND_ENABLE false
@ -1160,7 +1163,10 @@ static const bool audio_enable_menu_bgm = false;
/* Start netplay in spectator mode */
static const bool netplay_start_as_spectator = false;
/* Allow players (other than the host) to pause */
/* Netplay chat fading toggle */
static const bool netplay_fade_chat = true;
/* Allow players to pause */
static const bool netplay_allow_pausing = false;
/* Allow connections in slave mode */
@ -1188,9 +1194,10 @@ static const bool netplay_use_mitm_server = false;
#ifdef HAVE_NETWORKING
static const unsigned netplay_max_connections = 3;
static const unsigned netplay_share_digital = RARCH_NETPLAY_SHARE_DIGITAL_NO_PREFERENCE;
static const unsigned netplay_max_ping = 0;
static const unsigned netplay_share_analog = RARCH_NETPLAY_SHARE_ANALOG_NO_PREFERENCE;
static const unsigned netplay_share_digital = RARCH_NETPLAY_SHARE_DIGITAL_NO_PREFERENCE;
static const unsigned netplay_share_analog = RARCH_NETPLAY_SHARE_ANALOG_NO_PREFERENCE;
#endif
/* On save state load, block SRAM from being overwritten.

View File

@ -451,6 +451,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
RARCH_FPS_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PING_TOGGLE, RETROK_UNKNOWN,
RARCH_NETPLAY_PING_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
@ -472,6 +479,20 @@ static const struct retro_keybind retro_keybinds_1[] = {
RARCH_NETPLAY_GAME_WATCH, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PLAYER_CHAT, RETROK_UNKNOWN,
RARCH_NETPLAY_PLAYER_CHAT, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE, RETROK_UNKNOWN,
RARCH_NETPLAY_FADE_CHAT_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
@ -1005,6 +1026,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
RARCH_FPS_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PING_TOGGLE, RETROK_UNKNOWN,
RARCH_NETPLAY_PING_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
@ -1026,6 +1054,20 @@ static const struct retro_keybind retro_keybinds_1[] = {
RARCH_NETPLAY_GAME_WATCH, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PLAYER_CHAT, RETROK_UNKNOWN,
RARCH_NETPLAY_PLAYER_CHAT, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE, RETROK_UNKNOWN,
RARCH_NETPLAY_FADE_CHAT_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
@ -1569,6 +1611,13 @@ static const struct retro_keybind retro_keybinds_1[] = {
RARCH_FPS_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PING_TOGGLE, RETROK_UNKNOWN,
RARCH_NETPLAY_PING_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
@ -1590,6 +1639,20 @@ static const struct retro_keybind retro_keybinds_1[] = {
RARCH_NETPLAY_GAME_WATCH, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PLAYER_CHAT, RETROK_BACKQUOTE,
RARCH_NETPLAY_PLAYER_CHAT, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE, RETROK_UNKNOWN,
RARCH_NETPLAY_FADE_CHAT_TOGGLE, NO_BTN, NO_BTN, 0,
true
},
{
NULL, NULL,
AXIS_NONE, AXIS_NONE, AXIS_NONE,

View File

@ -333,9 +333,12 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = {
DECLARE_META_BIND(2, audio_mute, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE),
DECLARE_META_BIND(2, osk_toggle, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK),
DECLARE_META_BIND(2, fps_toggle, RARCH_FPS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE),
DECLARE_META_BIND(2, netplay_ping_toggle, RARCH_NETPLAY_PING_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PING_TOGGLE),
DECLARE_META_BIND(2, send_debug_info, RARCH_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO),
DECLARE_META_BIND(2, netplay_host_toggle, RARCH_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE),
DECLARE_META_BIND(2, netplay_game_watch, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH),
DECLARE_META_BIND(2, netplay_player_chat, RARCH_NETPLAY_PLAYER_CHAT, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PLAYER_CHAT),
DECLARE_META_BIND(2, netplay_fade_chat_toggle, RARCH_NETPLAY_FADE_CHAT_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE),
DECLARE_META_BIND(2, enable_hotkey, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY),
DECLARE_META_BIND(2, volume_up, RARCH_VOLUME_UP, MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP),
DECLARE_META_BIND(2, volume_down, RARCH_VOLUME_DOWN, MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN),
@ -1600,6 +1603,7 @@ static struct config_bool_setting *populate_settings_bool(
#ifdef HAVE_NETWORKING
SETTING_BOOL("netplay_public_announce", &settings->bools.netplay_public_announce, true, DEFAULT_NETPLAY_PUBLIC_ANNOUNCE, false);
SETTING_BOOL("netplay_start_as_spectator", &settings->bools.netplay_start_as_spectator, false, netplay_start_as_spectator, false);
SETTING_BOOL("netplay_fade_chat", &settings->bools.netplay_fade_chat, true, netplay_fade_chat, false);
SETTING_BOOL("netplay_allow_pausing", &settings->bools.netplay_allow_pausing, true, netplay_allow_pausing, false);
SETTING_BOOL("netplay_allow_slaves", &settings->bools.netplay_allow_slaves, true, netplay_allow_slaves, false);
SETTING_BOOL("netplay_require_slaves", &settings->bools.netplay_require_slaves, true, netplay_require_slaves, false);
@ -1622,6 +1626,7 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("netplay_request_device_p14", &settings->bools.netplay_request_devices[13], true, false, false);
SETTING_BOOL("netplay_request_device_p15", &settings->bools.netplay_request_devices[14], true, false, false);
SETTING_BOOL("netplay_request_device_p16", &settings->bools.netplay_request_devices[15], true, false, false);
SETTING_BOOL("netplay_ping_show", &settings->bools.netplay_ping_show, true, DEFAULT_NETPLAY_PING_SHOW, false);
SETTING_BOOL("network_on_demand_thumbnails", &settings->bools.network_on_demand_thumbnails, true, DEFAULT_NETWORK_ON_DEMAND_THUMBNAILS, false);
#endif
SETTING_BOOL("input_descriptor_label_show", &settings->bools.input_descriptor_label_show, true, input_descriptor_label_show, false);
@ -2215,6 +2220,7 @@ static struct config_uint_setting *populate_settings_uint(
SETTING_UINT("netplay_ip_port", &settings->uints.netplay_port, true, RARCH_DEFAULT_PORT, false);
SETTING_OVERRIDE(RARCH_OVERRIDE_SETTING_NETPLAY_IP_PORT);
SETTING_UINT("netplay_max_connections", &settings->uints.netplay_max_connections, true, netplay_max_connections, false);
SETTING_UINT("netplay_max_ping", &settings->uints.netplay_max_ping, true, netplay_max_ping, false);
SETTING_UINT("netplay_input_latency_frames_min",&settings->uints.netplay_input_latency_frames_min, true, 0, false);
SETTING_UINT("netplay_input_latency_frames_range",&settings->uints.netplay_input_latency_frames_range, true, 0, false);
SETTING_UINT("netplay_share_digital", &settings->uints.netplay_share_digital, true, netplay_share_digital, false);

View File

@ -201,6 +201,7 @@ typedef struct settings
unsigned netplay_port;
unsigned netplay_max_connections;
unsigned netplay_max_ping;
unsigned netplay_input_latency_frames_min;
unsigned netplay_input_latency_frames_range;
unsigned netplay_share_digital;
@ -760,6 +761,7 @@ typedef struct settings
/* Netplay */
bool netplay_public_announce;
bool netplay_start_as_spectator;
bool netplay_fade_chat;
bool netplay_allow_pausing;
bool netplay_allow_slaves;
bool netplay_require_slaves;
@ -767,6 +769,7 @@ typedef struct settings
bool netplay_nat_traversal;
bool netplay_use_mitm_server;
bool netplay_request_devices[MAX_USERS];
bool netplay_ping_show;
/* Network */
bool network_buildbot_auto_extract_archive;

View File

@ -79,6 +79,10 @@ static void INLINE gfx_widgets_font_free(gfx_widget_font_data_t *font_data)
/* Widgets list */
const static gfx_widget_t* const widgets[] = {
#ifdef HAVE_NETWORKING
&gfx_widget_netplay_chat,
&gfx_widget_netplay_ping,
#endif
#ifdef HAVE_SCREENSHOTS
&gfx_widget_screenshot,
#endif

View File

@ -378,6 +378,11 @@ extern const gfx_widget_t gfx_widget_libretro_message;
extern const gfx_widget_t gfx_widget_progress_message;
extern const gfx_widget_t gfx_widget_load_content_animation;
#ifdef HAVE_NETWORKING
extern const gfx_widget_t gfx_widget_netplay_chat;
extern const gfx_widget_t gfx_widget_netplay_ping;
#endif
#ifdef HAVE_CHEEVOS
extern const gfx_widget_t gfx_widget_achievement_popup;
extern const gfx_widget_t gfx_widget_leaderboard_display;

View File

@ -99,9 +99,12 @@ enum
RARCH_MUTE,
RARCH_OSK,
RARCH_FPS_TOGGLE,
RARCH_NETPLAY_PING_TOGGLE,
RARCH_SEND_DEBUG_INFO,
RARCH_NETPLAY_HOST_TOGGLE,
RARCH_NETPLAY_GAME_WATCH,
RARCH_NETPLAY_PLAYER_CHAT,
RARCH_NETPLAY_FADE_CHAT_TOGGLE,
RARCH_ENABLE_HOTKEY,
RARCH_VOLUME_UP,
RARCH_VOLUME_DOWN,

View File

@ -1282,6 +1282,10 @@ MSG_HASH(
MENU_ENUM_LABEL_STATISTICS_SHOW,
"statistics_show"
)
MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_PING_SHOW,
"netplay_ping_show"
)
MSG_HASH(
MENU_ENUM_LABEL_FRAME_THROTTLE_ENABLE,
"fastforward_ratio_throttle_enable"
@ -1972,6 +1976,10 @@ MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR,
"netplay_start_as_spectator"
)
MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_FADE_CHAT,
"netplay_fade_chat"
)
MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_ALLOW_PAUSING,
"netplay_allow_pausing"
@ -1988,6 +1996,10 @@ MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_MAX_CONNECTIONS,
"netplay_max_connections"
)
MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_MAX_PING,
"netplay_max_ping"
)
MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS,
"Search for and connect to netplay hosts on the local network."
@ -2836,6 +2848,10 @@ MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS,
"refresh_rooms"
)
MSG_HASH(
MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN,
"refresh_lan"
)
MSG_HASH(
MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY,
"scan_this_directory"

View File

@ -2666,6 +2666,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_META_FPS_TOGGLE,
"Switches 'frames per second' status indicator on/off."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PING_TOGGLE,
"Show Netplay Ping (Toggle)"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_PING_TOGGLE,
"Switches the ping counter for the current netplay room on/off."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO,
"Send Debug Info"
@ -2690,6 +2698,22 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_GAME_WATCH,
"Switches current netplay session between 'play' and 'spectate' modes."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PLAYER_CHAT,
"Netplay Player Chat"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_PLAYER_CHAT,
"Sends a chat message to the current netplay session."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE,
"Netplay Fade Chat Toggle"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE,
"Toggle between fading and static netplay chat messages."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY,
"Hotkey Enable"
@ -3907,6 +3931,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_MEMORY_UPDATE_INTERVAL,
"Memory usage display will be updated at the set interval in frames."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_PING_SHOW,
"Display Netplay Ping"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_PING_SHOW,
"Display the ping for the current netplay room."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_SHOW_LOAD_CONTENT_ANIMATION,
"\"Load Content\" Startup Notification"
@ -5258,6 +5290,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_MAX_CONNECTIONS,
"The maximum number of active connections that the host will accept before refusing new ones."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_MAX_PING,
"Ping Limiter"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_MAX_PING,
"The maximum connection latency (ping) that the host will accept. Set it to 0 for no limit."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD,
"Server Password"
@ -5282,13 +5322,21 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR,
"Start netplay in spectator mode."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_FADE_CHAT,
"Fade Chat"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_FADE_CHAT,
"Fade chat messages over time."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_PAUSING,
"Allow Pausing"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_PAUSING,
"Allow players to pause during netplay. The host can always pause regardless of this setting."
"Allow players to pause during netplay."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_ALLOW_SLAVES,
@ -6103,6 +6151,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS,
"Scan for netplay hosts."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_LAN,
"Refresh Netplay LAN List"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_LAN,
"Scan for netplay hosts on LAN."
)
/* Netplay > Host */
@ -10861,6 +10917,10 @@ MSG_HASH(
MSG_NETPLAY_ENTER_PASSWORD,
"Enter netplay server password:"
)
MSG_HASH(
MSG_NETPLAY_ENTER_CHAT,
"Enter netplay chat message:"
)
MSG_HASH(
MSG_DISCORD_CONNECTION_REQUEST,
"Do you want to allow connection from user:"
@ -11137,6 +11197,10 @@ MSG_HASH(
MSG_CONTENT_CRC32S_DIFFER,
"Content CRC32s differ. Cannot use different games."
)
MSG_HASH(
MSG_PING_TOO_HIGH,
"Your ping is too high for this host."
)
MSG_HASH(
MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT,
"Content loading skipped. Implementation will load it on its own."

View File

@ -5756,9 +5756,10 @@ static int action_ok_netplay_connect_room(const char *path,
if (net_st->room_list[room_index].host_method == NETPLAY_HOST_METHOD_MITM)
snprintf(tmp_hostname,
sizeof(tmp_hostname),
"%s|%d",
"%s|%d|%s",
net_st->room_list[room_index].mitm_address,
net_st->room_list[room_index].mitm_port);
net_st->room_list[room_index].mitm_port,
net_st->room_list[room_index].mitm_session);
else
snprintf(tmp_hostname,
sizeof(tmp_hostname),
@ -5783,224 +5784,168 @@ static int action_ok_netplay_connect_room(const char *path,
return 0;
}
#ifdef HAVE_NETPLAYDISCOVERY
static int action_ok_netplay_lan_scan(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
struct netplay_host_list *hosts = NULL;
struct netplay_host *host = NULL;
/* Figure out what host we're connecting to */
if (!netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts))
return -1;
if (entry_idx >= hosts->size)
return -1;
host = &hosts->hosts[entry_idx];
/* Enable Netplay client mode */
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
generic_action_ok_command(CMD_EVENT_NETPLAY_DEINIT);
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
/* Enable Netplay */
if (command_event(CMD_EVENT_NETPLAY_INIT_DIRECT, (void *) host))
return generic_action_ok_command(CMD_EVENT_RESUME);
return -1;
}
static void netplay_lan_scan_callback(retro_task_t *task,
void *task_data,
void *user_data, const char *error)
{
struct netplay_host_list *netplay_hosts = NULL;
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
unsigned menu_type = 0;
const char *label = NULL;
const char *path = NULL;
/* TODO/FIXME: I have no idea what this is supposed to be
* doing...
* As it stands, this function will never get past the
* following sanity check (i.e. netplay_lan_scan_callback()
* will never be called when we are viewing the 'lan scan
* settings' list, since this list doesn't even exist...).
* Moreover, any menu entries that get added here
* (menu_entries_append_enum()) will be erased by the
* subsequent netplay_refresh_rooms_cb() callback - and
* menu entries should never be added outside of
* menu_displaylist.c anyway.
* This is some legacy garbage, and someone who understands
* netplay needs to rip it all out. */
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
/* Don't push the results if we left the LAN scan menu */
if (!string_is_equal(label,
msg_hash_to_str(
MENU_ENUM_LABEL_DEFERRED_NETPLAY_LAN_SCAN_SETTINGS_LIST)))
return;
if (!netplay_discovery_driver_ctl(
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES,
(void *) &netplay_hosts))
return;
if (netplay_hosts->size > 0)
{
unsigned i;
file_list_t *file_list = menu_entries_get_selection_buf_ptr(0);
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list);
for (i = 0; i < netplay_hosts->size; i++)
{
struct netplay_host *host = &netplay_hosts->hosts[i];
menu_entries_append_enum(file_list,
host->nick,
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_CONNECT_TO),
MENU_ENUM_LABEL_NETPLAY_CONNECT_TO,
MENU_NETPLAY_LAN_SCAN, 0, 0);
}
}
}
#endif
static void netplay_refresh_rooms_cb(retro_task_t *task,
void *task_data, void *user_data, const char *err)
void *task_data, void *user_data, const char *error)
{
char *new_data = NULL;
const char *path = NULL;
const char *label = NULL;
unsigned menu_type = 0;
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
net_driver_state_t *net_st = networking_state_get_ptr();
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
char *new_data = NULL;
const char *path = NULL;
const char *label = NULL;
unsigned menu_type = 0;
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
net_driver_state_t *net_st = networking_state_get_ptr();
http_transfer_data_t *data = task_data;
bool refresh = false;
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
/* Don't push the results if we left the netplay menu */
if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB))
&& !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
if (!string_is_equal(label,
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) &&
!string_is_equal(label,
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
return;
if (!data || err)
goto finish;
new_data = (char*)realloc(data->data, data->len + 1);
if (error)
{
RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED),
error);
return;
}
if (!data || !data->data || !data->len || data->status != 200)
{
RARCH_ERR("%s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED));
return;
}
new_data = realloc(data->data, data->len + 1);
if (!new_data)
goto finish;
return;
data->data = new_data;
data->data[data->len] = '\0';
if (!string_ends_with_size(data->data, "registry.lpl",
strlen(data->data),
STRLEN_CONST("registry.lpl")))
if (net_st->room_list)
free(net_st->room_list);
net_st->room_list = NULL;
net_st->room_count = 0;
if (!string_is_empty(data->data))
{
if (string_is_empty(data->data))
net_st->room_count = 0;
else
{
char s[PATH_MAX_LENGTH];
unsigned i = 0;
unsigned j = 0;
struct netplay_host_list *lan_hosts = NULL;
int lan_room_count = 0;
bool refresh = false;
int i;
#ifdef HAVE_NETPLAYDISCOVERY
netplay_discovery_driver_ctl(RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &lan_hosts);
if (lan_hosts)
lan_room_count = (int)lan_hosts->size;
#endif
netplay_rooms_parse(data->data);
netplay_rooms_parse(data->data);
net_st->room_count = netplay_rooms_get_count();
net_st->room_list = calloc(net_st->room_count,
sizeof(*net_st->room_list));
if (net_st->room_list)
free(net_st->room_list);
/* TODO/FIXME - right now, a LAN and non-LAN netplay session might appear
* in the same list. If both entries are available, we want to show only
* the LAN one. */
net_st->room_count = netplay_rooms_get_count();
net_st->room_list = (struct netplay_room*)
calloc(net_st->room_count + lan_room_count,
sizeof(struct netplay_room));
for (i = 0; i < (unsigned)net_st->room_count; i++)
memcpy(&net_st->room_list[i], netplay_room_get(i), sizeof(net_st->room_list[i]));
if (lan_room_count != 0)
{
for (i = net_st->room_count; i < (unsigned)(net_st->room_count + lan_room_count); i++)
{
struct netplay_host *host = &lan_hosts->hosts[j++];
strlcpy(net_st->room_list[i].nickname,
host->nick,
sizeof(net_st->room_list[i].nickname));
strlcpy(net_st->room_list[i].address,
host->address,
INET6_ADDRSTRLEN);
strlcpy(net_st->room_list[i].corename,
host->core,
sizeof(net_st->room_list[i].corename));
strlcpy(net_st->room_list[i].retroarch_version,
host->retroarch_version,
sizeof(net_st->room_list[i].retroarch_version));
strlcpy(net_st->room_list[i].coreversion,
host->core_version,
sizeof(net_st->room_list[i].coreversion));
strlcpy(net_st->room_list[i].gamename,
host->content,
sizeof(net_st->room_list[i].gamename));
strlcpy(net_st->room_list[i].frontend,
host->frontend,
sizeof(net_st->room_list[i].frontend));
strlcpy(net_st->room_list[i].subsystem_name,
host->subsystem_name,
sizeof(net_st->room_list[i].subsystem_name));
net_st->room_list[i].port = host->port;
net_st->room_list[i].gamecrc = host->content_crc;
net_st->room_list[i].timestamp = 0;
net_st->room_list[i].lan = true;
snprintf(s, sizeof(s),
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME),
net_st->room_list[i].nickname);
}
net_st->room_count += lan_room_count;
}
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
}
for (i = 0; i < net_st->room_count; i++)
memcpy(&net_st->room_list[i], netplay_room_get(i),
sizeof(*net_st->room_list));
}
finish:
if (err)
RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), err);
if (user_data)
free(user_data);
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
}
static int action_ok_push_netplay_refresh_rooms(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
char url [2048] = "http://lobby.libretro.com/list/";
#ifdef HAVE_NETPLAYDISCOVERY
task_push_netplay_lan_scan(netplay_lan_scan_callback);
#ifndef NETPLAY_TEST_BUILD
const char *url = "http://lobby.libretro.com/list";
#else
const char *url = "http://lobbytest.libretro.com/list";
#endif
task_push_http_transfer(url, true, NULL, netplay_refresh_rooms_cb, NULL);
return 0;
}
#ifdef HAVE_NETPLAYDISCOVERY
static void netplay_refresh_lan_cb(retro_task_t *task,
void *task_data, void *user_data, const char *error)
{
const char *path = NULL;
const char *label = NULL;
unsigned menu_type = 0;
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
net_driver_state_t *net_st = networking_state_get_ptr();
struct netplay_host_list *hosts = NULL;
bool refresh = false;
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
/* Don't push the results if we left the netplay menu */
if (!string_is_equal(label,
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) &&
!string_is_equal(label,
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
goto finished;
if (!netplay_discovery_driver_ctl(
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts) ||
!hosts)
goto finished;
if (net_st->room_list)
free(net_st->room_list);
net_st->room_list = NULL;
net_st->room_count = 0;
if (hosts->size)
{
int i;
net_st->room_count = hosts->size;
net_st->room_list = calloc(net_st->room_count,
sizeof(*net_st->room_list));
for (i = 0; i < net_st->room_count; i++)
{
struct netplay_host *host = &hosts->hosts[i];
struct netplay_room *room = &net_st->room_list[i];
room->port = host->port;
room->gamecrc = host->content_crc;
strlcpy(room->retroarch_version, host->retroarch_version,
sizeof(room->retroarch_version));
strlcpy(room->nickname, host->nick,
sizeof(room->nickname));
strlcpy(room->subsystem_name, host->subsystem_name,
sizeof(room->subsystem_name));
strlcpy(room->corename, host->core,
sizeof(room->corename));
strlcpy(room->frontend, host->frontend,
sizeof(room->frontend));
strlcpy(room->coreversion, host->core_version,
sizeof(room->coreversion));
strlcpy(room->gamename, host->content,
sizeof(room->gamename));
strlcpy(room->address, host->address,
sizeof(room->address));
room->has_password = host->has_password;
room->has_spectate_password = host->has_spectate_password;
room->lan = true;
}
}
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
finished:
deinit_netplay_discovery();
}
static int action_ok_push_netplay_refresh_lan(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
task_push_netplay_lan_scan(netplay_refresh_lan_cb);
return 0;
}
#endif
#endif
DEFAULT_ACTION_OK_DL_PUSH(action_ok_content_collection_list, FILEBROWSER_SELECT_COLLECTION, ACTION_OK_DL_CONTENT_COLLECTION_LIST, NULL)
@ -7758,6 +7703,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
{MENU_ENUM_LABEL_DOWNLOAD_PL_ENTRY_THUMBNAILS, action_ok_pl_entry_content_thumbnails},
{MENU_ENUM_LABEL_UPDATE_LAKKA, action_ok_lakka_list},
{MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS, action_ok_push_netplay_refresh_rooms},
#ifdef HAVE_NETPLAYDISCOVERY
{MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN, action_ok_push_netplay_refresh_lan},
#endif
#endif
#ifdef HAVE_VIDEO_LAYOUT
{MENU_ENUM_LABEL_ONSCREEN_VIDEO_LAYOUT_SETTINGS, action_ok_onscreen_video_layout_list},
@ -8473,11 +8421,6 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs,
#ifdef HAVE_WIFI
BIND_ACTION_OK(cbs, action_ok_wifi);
#endif
#endif
break;
case MENU_NETPLAY_LAN_SCAN:
#if defined(HAVE_NETWORKING) && defined(HAVE_NETPLAYDISCOVERY)
BIND_ACTION_OK(cbs, action_ok_netplay_lan_scan);
#endif
break;
case FILE_TYPE_CURSOR:

View File

@ -253,6 +253,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_framecount_show, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_memory_show, MENU_ENUM_SUBLABEL_MEMORY_SHOW)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_memory_update_interval, MENU_ENUM_SUBLABEL_MEMORY_UPDATE_INTERVAL)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_statistics_show, MENU_ENUM_SUBLABEL_STATISTICS_SHOW)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_ping_show, MENU_ENUM_SUBLABEL_NETPLAY_PING_SHOW)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_settings, MENU_ENUM_SUBLABEL_NETPLAY)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_user_bind_settings, MENU_ENUM_SUBLABEL_INPUT_USER_BINDS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_hotkey_settings, MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS)
@ -287,9 +288,12 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_screenshot, ME
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_mute, MENU_ENUM_SUBLABEL_INPUT_META_MUTE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_osk, MENU_ENUM_SUBLABEL_INPUT_META_OSK)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_fps_toggle, MENU_ENUM_SUBLABEL_INPUT_META_FPS_TOGGLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_netplay_ping_toggle, MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_PING_TOGGLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_send_debug_info, MENU_ENUM_SUBLABEL_INPUT_META_SEND_DEBUG_INFO)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_netplay_host_toggle, MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_HOST_TOGGLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_netplay_game_watch, MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_GAME_WATCH)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_netplay_player_chat, MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_PLAYER_CHAT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_netplay_fade_chat_toggle, MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_enable_hotkey, MENU_ENUM_SUBLABEL_INPUT_META_ENABLE_HOTKEY)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_volume_up, MENU_ENUM_SUBLABEL_INPUT_META_VOLUME_UP)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_volume_down, MENU_ENUM_SUBLABEL_INPUT_META_VOLUME_DOWN)
@ -613,9 +617,11 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_public_announce, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_ip_address, MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_tcp_udp_port, MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_max_connections, MENU_ENUM_SUBLABEL_NETPLAY_MAX_CONNECTIONS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_max_ping, MENU_ENUM_SUBLABEL_NETPLAY_MAX_PING)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_password, MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_spectate_password, MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_start_as_spectator, MENU_ENUM_SUBLABEL_NETPLAY_START_AS_SPECTATOR)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_fade_chat, MENU_ENUM_SUBLABEL_NETPLAY_FADE_CHAT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_allow_pausing, MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_PAUSING)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_allow_slaves, MENU_ENUM_SUBLABEL_NETPLAY_ALLOW_SLAVES)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_require_slaves, MENU_ENUM_SUBLABEL_NETPLAY_REQUIRE_SLAVES)
@ -671,6 +677,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_updater_show_experimental_cores
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_updater_auto_backup, MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_BACKUP)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_core_updater_auto_backup_history_size, MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_BACKUP_HISTORY_SIZE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_refresh_rooms, MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_netplay_refresh_lan, MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_LAN)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_rename_entry, MENU_ENUM_SUBLABEL_RENAME_ENTRY)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_delete_entry, MENU_ENUM_SUBLABEL_DELETE_ENTRY)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_information, MENU_ENUM_SUBLABEL_INFORMATION)
@ -1876,6 +1883,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case RARCH_FPS_TOGGLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_fps_toggle);
return 0;
case RARCH_NETPLAY_PING_TOGGLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_netplay_ping_toggle);
return 0;
case RARCH_SEND_DEBUG_INFO:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_send_debug_info);
return 0;
@ -1885,6 +1895,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case RARCH_NETPLAY_GAME_WATCH:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_netplay_game_watch);
return 0;
case RARCH_NETPLAY_PLAYER_CHAT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_netplay_player_chat);
return 0;
case RARCH_NETPLAY_FADE_CHAT_TOGGLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_netplay_fade_chat_toggle);
return 0;
case RARCH_ENABLE_HOTKEY:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_meta_enable_hotkey);
return 0;
@ -2850,6 +2866,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_refresh_rooms);
break;
case MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_refresh_lan);
break;
case MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_updater_auto_extract_archive);
break;
@ -2994,6 +3013,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_start_as_spectator);
break;
case MENU_ENUM_LABEL_NETPLAY_FADE_CHAT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_fade_chat);
break;
case MENU_ENUM_LABEL_NETPLAY_ALLOW_PAUSING:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_allow_pausing);
break;
@ -3012,6 +3034,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_spectate_password);
break;
case MENU_ENUM_LABEL_NETPLAY_MAX_PING:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_max_ping);
break;
case MENU_ENUM_LABEL_NETPLAY_MAX_CONNECTIONS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_max_connections);
break;
@ -3916,6 +3941,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_max_swapchain_images);
break;
case MENU_ENUM_LABEL_NETPLAY_PING_SHOW:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_ping_show);
break;
case MENU_ENUM_LABEL_STATISTICS_SHOW:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_statistics_show);
break;

View File

@ -10571,6 +10571,7 @@ static void materialui_list_insert(
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES)) ||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET)) ||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS)) ||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN)) ||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT)) ||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST)) ||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_REMAP_FILE_LOAD)) ||

View File

@ -1876,6 +1876,10 @@ static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_ROOM];
case MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_RELOAD];
#ifdef HAVE_NETPLAYDISCOVERY
case MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_RELOAD];
#endif
#endif
case MENU_ENUM_LABEL_REBOOT:
case MENU_ENUM_LABEL_RESET_TO_DEFAULT_CONFIG:

View File

@ -2824,6 +2824,10 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
return xmb->textures.list[XMB_TEXTURE_ROOM];
case MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS:
return xmb->textures.list[XMB_TEXTURE_RELOAD];
#ifdef HAVE_NETPLAYDISCOVERY
case MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN:
return xmb->textures.list[XMB_TEXTURE_RELOAD];
#endif
case MENU_ENUM_LABEL_NETWORK_INFORMATION:
case MENU_ENUM_LABEL_NETWORK_SETTINGS:
case MENU_ENUM_LABEL_WIFI_SETTINGS:

View File

@ -7302,9 +7302,11 @@ unsigned menu_displaylist_build_list(
{MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS, PARSE_ONLY_STRING, true},
{MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT, PARSE_ONLY_UINT, true},
{MENU_ENUM_LABEL_NETPLAY_MAX_CONNECTIONS, PARSE_ONLY_UINT, true},
{MENU_ENUM_LABEL_NETPLAY_MAX_PING, PARSE_ONLY_UINT, true},
{MENU_ENUM_LABEL_NETPLAY_PASSWORD, PARSE_ONLY_STRING, true},
{MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD, PARSE_ONLY_STRING, true},
{MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_NETPLAY_FADE_CHAT, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_NETPLAY_ALLOW_PAUSING, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_NETPLAY_ALLOW_SLAVES, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_NETPLAY_REQUIRE_SLAVES, PARSE_ONLY_BOOL, false},
@ -8633,6 +8635,9 @@ unsigned menu_displaylist_build_list(
{MENU_ENUM_LABEL_STATISTICS_SHOW, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_MEMORY_SHOW, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_MEMORY_UPDATE_INTERVAL, PARSE_ONLY_UINT, false },
#if defined(HAVE_NETWORKING) && defined(HAVE_GFX_WIDGETS)
{MENU_ENUM_LABEL_NETPLAY_PING_SHOW, PARSE_ONLY_BOOL, false },
#endif
{MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT_ANIMATION, PARSE_ONLY_BOOL, false },
{MENU_ENUM_LABEL_NOTIFICATION_SHOW_AUTOCONFIG, PARSE_ONLY_BOOL, false },
#ifdef HAVE_CHEATS
@ -8676,6 +8681,12 @@ unsigned menu_displaylist_build_list(
build_list[i].checked = true;
break;
#ifdef HAVE_GFX_WIDGETS
#ifdef HAVE_NETWORKING
case MENU_ENUM_LABEL_NETPLAY_PING_SHOW:
if (widgets_active)
build_list[i].checked = true;
break;
#endif
case MENU_ENUM_LABEL_MENU_SHOW_LOAD_CONTENT_ANIMATION:
if (widgets_active)
build_list[i].checked = true;
@ -9666,12 +9677,9 @@ static unsigned menu_displaylist_build_shader_parameter(
#ifdef HAVE_NETWORKING
unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
{
char s[8300];
int i = 0;
unsigned count = 0;
net_driver_state_t *net_st = networking_state_get_ptr();
s[0] = '\0';
int i;
unsigned count = 0;
net_driver_state_t *net_st = networking_state_get_ptr();
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, list);
@ -9715,71 +9723,77 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
MENU_SETTING_ACTION, 0, 0))
count++;
if (net_st->room_count != 0)
{
for (i = 0; i < net_st->room_count; i++)
{
char country[8];
char passworded[64];
if (!net_st->room_list[i].lan &&
!string_is_empty(net_st->room_list[i].country))
snprintf(country, sizeof(country),
"(%s)", net_st->room_list[i].country);
else
*country = '\0';
if (net_st->room_list[i].has_password ||
net_st->room_list[i].has_spectate_password)
snprintf(passworded, sizeof(passworded),
"[%s]", msg_hash_to_str(MSG_ROOM_PASSWORDED));
else
*passworded = '\0';
/* Uncomment this to debug mismatched room parameters*/
#if 0
RARCH_LOG("[Lobby]: Room Data: %d\n"
"Nickname: %s\n"
"Address: %s\n"
"Port: %d\n"
"Core: %s\n"
"Core Version: %s\n"
"Game: %s\n"
"Game CRC: %08x\n"
"Timestamp: %d\n", room_data->elems[j + 6].data,
net_st->room_list[i].nickname,
net_st->room_list[i].address,
net_st->room_list[i].port,
net_st->room_list[i].corename,
net_st->room_list[i].coreversion,
net_st->room_list[i].gamename,
net_st->room_list[i].gamecrc,
net_st->room_list[i].timestamp);
#ifdef HAVE_NETPLAYDISCOVERY
if (menu_entries_append_enum(list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_LAN),
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN),
MENU_ENUM_LABEL_NETPLAY_REFRESH_LAN,
MENU_SETTING_ACTION, 0, 0))
count++;
#endif
snprintf(s, sizeof(s), "%s%s: %s%s",
passworded,
net_st->room_list[i].lan
? msg_hash_to_str(MSG_LOCAL)
: (net_st->room_list[i].host_method
== NETPLAY_HOST_METHOD_MITM
? msg_hash_to_str(MSG_INTERNET_RELAY)
: msg_hash_to_str(MSG_INTERNET)),
net_st->room_list[i].nickname,
country
);
for (i = 0; i < net_st->room_count; i++)
{
char buf[8192];
char passworded[64];
char country[8];
const char *room_type;
struct netplay_room *room = &net_st->room_list[i];
if (menu_entries_append_enum(list,
s,
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM),
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
(unsigned)(MENU_SETTINGS_NETPLAY_ROOMS_START + i), 0, 0))
count++;
}
if (room->has_password || room->has_spectate_password)
snprintf(passworded, sizeof(passworded), "[%s] ",
msg_hash_to_str(MSG_ROOM_PASSWORDED));
else
*passworded = '\0';
netplay_rooms_free();
if (!room->lan && !string_is_empty(room->country))
snprintf(country, sizeof(country), " (%s)",
room->country);
else
*country = '\0';
if (room->lan)
room_type = msg_hash_to_str(MSG_LOCAL);
else if (room->host_method == NETPLAY_HOST_METHOD_MITM)
room_type = msg_hash_to_str(MSG_INTERNET_RELAY);
else
room_type = msg_hash_to_str(MSG_INTERNET);
snprintf(buf, sizeof(buf), "%s%s: %s%s",
passworded, room_type,
room->nickname, country);
if (menu_entries_append_enum(list,
buf,
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM),
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
(unsigned)(MENU_SETTINGS_NETPLAY_ROOMS_START + i), 0, 0))
count++;
/* Uncomment this to debug mismatched room parameters*/
#if 0
RARCH_LOG("[Lobby]: Room Data: %d\n"
"Nickname: %s\n"
"Address: %s\n"
"Port: %d\n"
"Core: %s\n"
"Core Version: %s\n"
"Game: %s\n"
"Game CRC: %08x\n"
"Timestamp: %d\n", room_data->elems[j + 6].data,
room->nickname,
room->address,
room->port,
room->corename,
room->coreversion,
room->gamename,
room->gamecrc,
room->timestamp);
#endif
}
netplay_rooms_free();
return count;
}
@ -9924,6 +9938,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
menu_displaylist_build_info_selective_t build_list[] = {
{MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT, PARSE_ONLY_UINT, true},
{MENU_ENUM_LABEL_NETPLAY_MAX_CONNECTIONS, PARSE_ONLY_UINT, true},
{MENU_ENUM_LABEL_NETPLAY_MAX_PING, PARSE_ONLY_UINT, true},
{MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER, PARSE_ONLY_BOOL, true },
{MENU_ENUM_LABEL_NETPLAY_MITM_SERVER, PARSE_ONLY_STRING, false},

View File

@ -38,6 +38,10 @@
#include "../accessibility.h"
#endif
#ifdef HAVE_NETWORKING
#include "../network/netplay/netplay.h"
#endif
#include "../audio/audio_driver.h"
#include "menu_driver.h"
@ -6690,7 +6694,12 @@ void menu_driver_toggle(
if (settings)
{
#ifdef HAVE_NETWORKING
pause_libretro = settings->bools.menu_pause_libretro &&
netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL);
#else
pause_libretro = settings->bools.menu_pause_libretro;
#endif
#ifdef HAVE_AUDIOMIXER
audio_enable_menu = settings->bools.audio_enable_menu;
#endif

View File

@ -14462,6 +14462,26 @@ static bool setting_append_list(
SD_FLAG_NONE);
#ifdef HAVE_GFX_WIDGETS
#ifdef HAVE_NETWORKING
CONFIG_BOOL(
list, list_info,
&settings->bools.netplay_ping_show,
MENU_ENUM_LABEL_NETPLAY_PING_SHOW,
MENU_ENUM_LABEL_VALUE_NETPLAY_PING_SHOW,
DEFAULT_NETPLAY_PING_SHOW,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
(*list)[list_info->index - 1].action_ok = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_left = &setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_right = &setting_bool_action_right_with_refresh;
#endif
CONFIG_BOOL(
list, list_info,
&settings->bools.menu_show_load_content_animation,
@ -19204,6 +19224,21 @@ static bool setting_append_list(
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
menu_settings_list_current_add_range(list, list_info, 1, 31, 1, true, true);
CONFIG_UINT(
list, list_info,
&settings->uints.netplay_max_ping,
MENU_ENUM_LABEL_NETPLAY_MAX_PING,
MENU_ENUM_LABEL_VALUE_NETPLAY_MAX_PING,
netplay_max_ping,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_SPINBOX;
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
menu_settings_list_current_add_range(list, list_info, 0, 500, 25, true, true);
CONFIG_STRING(
list, list_info,
settings->paths.netplay_password,
@ -19251,6 +19286,21 @@ static bool setting_append_list(
general_read_handler,
SD_FLAG_NONE);
CONFIG_BOOL(
list, list_info,
&settings->bools.netplay_fade_chat,
MENU_ENUM_LABEL_NETPLAY_FADE_CHAT,
MENU_ENUM_LABEL_VALUE_NETPLAY_FADE_CHAT,
netplay_fade_chat,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
CONFIG_BOOL(
list, list_info,
&settings->bools.netplay_allow_pausing,

View File

@ -200,6 +200,7 @@ enum msg_hash_enums
MSG_NETPLAY_ENDIAN_DEPENDENT,
MSG_NETPLAY_PLATFORM_DEPENDENT,
MSG_NETPLAY_ENTER_PASSWORD,
MSG_NETPLAY_ENTER_CHAT,
MSG_NETPLAY_INCORRECT_PASSWORD,
MSG_NETPLAY_SERVER_NAMED_HANGUP,
MSG_NETPLAY_SERVER_HANGUP,
@ -330,6 +331,7 @@ enum msg_hash_enums
MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER,
MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION,
MSG_CONTENT_CRC32S_DIFFER,
MSG_PING_TOO_HIGH,
MSG_RECORDING_TERMINATED_DUE_TO_RESIZE,
MSG_FAILED_TO_START_RECORDING,
MSG_REVERTING_SAVEFILE_DIRECTORY_TO,
@ -878,9 +880,12 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PING_TOGGLE,
MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PLAYER_CHAT,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE,
MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY,
MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP,
MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN,
@ -935,9 +940,12 @@ enum msg_hash_enums
MENU_ENUM_SUBLABEL_INPUT_META_MUTE,
MENU_ENUM_SUBLABEL_INPUT_META_OSK,
MENU_ENUM_SUBLABEL_INPUT_META_FPS_TOGGLE,
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_PING_TOGGLE,
MENU_ENUM_SUBLABEL_INPUT_META_SEND_DEBUG_INFO,
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_HOST_TOGGLE,
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_GAME_WATCH,
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_PLAYER_CHAT,
MENU_ENUM_SUBLABEL_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE,
MENU_ENUM_SUBLABEL_INPUT_META_ENABLE_HOTKEY,
MENU_ENUM_SUBLABEL_INPUT_META_VOLUME_UP,
MENU_ENUM_SUBLABEL_INPUT_META_VOLUME_DOWN,
@ -1633,6 +1641,7 @@ enum msg_hash_enums
MENU_LABEL(SCAN_DIRECTORY),
MENU_LABEL(SCAN_FILE),
MENU_LABEL(NETPLAY_REFRESH_ROOMS),
MENU_LABEL(NETPLAY_REFRESH_LAN),
MENU_LABEL(NETPLAY_ROOM_NICKNAME),
MENU_LABEL(NETPLAY_ROOM_NICKNAME_LAN),
MENU_LABEL(ADD_CONTENT_LIST),
@ -1906,6 +1915,7 @@ enum msg_hash_enums
MENU_LABEL(NETPLAY_DELAY_FRAMES),
MENU_LABEL(NETPLAY_PUBLIC_ANNOUNCE),
MENU_LABEL(NETPLAY_START_AS_SPECTATOR),
MENU_LABEL(NETPLAY_FADE_CHAT),
MENU_LABEL(NETPLAY_ALLOW_PAUSING),
MENU_LABEL(NETPLAY_ALLOW_SLAVES),
MENU_LABEL(NETPLAY_REQUIRE_SLAVES),
@ -1916,8 +1926,10 @@ enum msg_hash_enums
MENU_LABEL(NETPLAY_SPECTATOR_MODE_ENABLE),
MENU_LABEL(NETPLAY_TCP_UDP_PORT),
MENU_LABEL(NETPLAY_MAX_CONNECTIONS),
MENU_LABEL(NETPLAY_MAX_PING),
MENU_LABEL(NETPLAY_NAT_TRAVERSAL),
MENU_LABEL(NETPLAY_REQUEST_DEVICE_I),
MENU_LABEL(NETPLAY_PING_SHOW),
MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1,
MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_LAST = MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + MAX_USERS,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE,

View File

@ -161,7 +161,7 @@ static void handle_discord_join_cb(retro_task_t *task,
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
discord_state_t *discord_st = &discord_state_st;
if (!data || err || !data->data)
if (!data || err || !data->data || !data->len)
goto finish;
data->data = (char*)realloc(data->data, data->len + 1);
@ -172,17 +172,17 @@ static void handle_discord_join_cb(retro_task_t *task,
if (room)
{
bool host_method_is_mitm = room->host_method == NETPLAY_HOST_METHOD_MITM;
const char *srv_address = host_method_is_mitm ? room->mitm_address : room->address;
unsigned srv_port = host_method_is_mitm ? room->mitm_port : room->port;
if (room->host_method == NETPLAY_HOST_METHOD_MITM)
snprintf(join_hostname, sizeof(join_hostname), "%s|%d|%s",
room->mitm_address, room->mitm_port, room->mitm_session);
else
snprintf(join_hostname, sizeof(join_hostname), "%s|%d",
room->address, room->port);
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
deinit_netplay();
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
snprintf(join_hostname, sizeof(join_hostname), "%s|%d",
srv_address, srv_port);
task_push_netplay_crc_scan(room->gamecrc,
room->gamename, join_hostname, room->corename, room->subsystem_name);
discord_st->connecting = true;

View File

@ -2,6 +2,7 @@
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2016-2017 - Gregor Richards
* Copyright (C) 2021-2021 - Roberto V. Rampim
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -35,13 +36,23 @@
#include "../../core.h"
#define NETPLAY_HOST_STR_LEN 32
#include "netplay_protocol.h"
#define NETPLAY_NICK_LEN 32
#define NETPLAY_HOST_STR_LEN 32
#define NETPLAY_HOST_LONGSTR_LEN 256
#define NETPLAY_CHAT_MAX_MESSAGES 5
#define NETPLAY_CHAT_MAX_SIZE 96
#define NETPLAY_CHAT_FRAME_TIME 900
#define NETPLAY_CHAT_NICKNAME_COLOR 0x00800000
#define NETPLAY_CHAT_MESSAGE_COLOR 0xFFFFFF00
enum rarch_netplay_ctl_state
{
RARCH_NETPLAY_CTL_NONE = 0,
RARCH_NETPLAY_CTL_GAME_WATCH,
RARCH_NETPLAY_CTL_PLAYER_CHAT,
RARCH_NETPLAY_CTL_POST_FRAME,
RARCH_NETPLAY_CTL_PRE_FRAME,
RARCH_NETPLAY_CTL_ENABLE_SERVER,
@ -52,6 +63,7 @@ enum rarch_netplay_ctl_state
RARCH_NETPLAY_CTL_IS_SERVER,
RARCH_NETPLAY_CTL_IS_CONNECTED,
RARCH_NETPLAY_CTL_IS_DATA_INITED,
RARCH_NETPLAY_CTL_ALLOW_PAUSE,
RARCH_NETPLAY_CTL_PAUSE,
RARCH_NETPLAY_CTL_UNPAUSE,
RARCH_NETPLAY_CTL_LOAD_SAVESTATE,
@ -104,17 +116,16 @@ typedef struct netplay netplay_t;
struct ad_packet
{
uint32_t header;
uint32_t protocol_version;
uint32_t port;
char address[NETPLAY_HOST_STR_LEN];
char retroarch_version[NETPLAY_HOST_STR_LEN];
char nick[NETPLAY_HOST_STR_LEN];
char frontend[NETPLAY_HOST_STR_LEN];
char core[NETPLAY_HOST_STR_LEN];
char core_version[NETPLAY_HOST_STR_LEN];
char content[NETPLAY_HOST_LONGSTR_LEN];
char content_crc[NETPLAY_HOST_STR_LEN];
char subsystem_name[NETPLAY_HOST_STR_LEN];
int content_crc;
int port;
uint32_t has_password;
char nick[NETPLAY_NICK_LEN];
char frontend[NETPLAY_HOST_STR_LEN];
char core[NETPLAY_HOST_STR_LEN];
char core_version[NETPLAY_HOST_STR_LEN];
char retroarch_version[NETPLAY_HOST_STR_LEN];
char content[NETPLAY_HOST_LONGSTR_LEN];
char subsystem_name[NETPLAY_HOST_LONGSTR_LEN];
};
typedef struct mitm_server
@ -133,7 +144,7 @@ static const mitm_server_t netplay_mitm_server_list[] = {
struct netplay_room
{
struct netplay_room *next;
int id;
int id;
int port;
int mitm_port;
int gamecrc;
@ -148,11 +159,12 @@ struct netplay_room
char coreversion [256];
char gamename [256];
char address [256];
char mitm_handle [33];
char mitm_address [256];
char mitm_session [33];
bool has_password;
bool has_spectate_password;
bool lan;
bool fixed;
};
struct netplay_rooms
@ -163,18 +175,18 @@ struct netplay_rooms
struct netplay_host
{
struct sockaddr addr;
socklen_t addrlen;
int content_crc;
int port;
char address[NETPLAY_HOST_STR_LEN];
char nick[NETPLAY_HOST_STR_LEN];
char nick[NETPLAY_NICK_LEN];
char frontend[NETPLAY_HOST_STR_LEN];
char core[NETPLAY_HOST_STR_LEN];
char core_version[NETPLAY_HOST_STR_LEN];
char retroarch_version[NETPLAY_HOST_STR_LEN];
char content[NETPLAY_HOST_LONGSTR_LEN];
char subsystem_name[NETPLAY_HOST_LONGSTR_LEN];
bool has_password;
bool has_spectate_password;
};
struct netplay_host_list
@ -183,32 +195,60 @@ struct netplay_host_list
size_t size;
};
struct netplay_chat_data
{
char nick[NETPLAY_NICK_LEN];
char msg[NETPLAY_CHAT_MAX_SIZE];
uint32_t frames;
};
struct netplay_chat_buffer
{
char nick[NETPLAY_NICK_LEN];
char msg[NETPLAY_CHAT_MAX_SIZE];
uint8_t alpha;
};
struct netplay_chat
{
struct
{
struct netplay_chat_data data;
struct netplay_chat_buffer buffer;
} messages[NETPLAY_CHAT_MAX_MESSAGES];
uint32_t message_slots;
};
typedef struct
{
netplay_t *data; /* Used while Netplay is running */
struct netplay_room host_room; /* ptr alignment */
netplay_t *handshake_password;
struct netplay_room *room_list;
struct netplay_rooms *rooms_data;
#ifdef HAVE_NETPLAYDISCOVERY
/* LAN discovery sockets */
int lan_ad_server_fd;
int lan_ad_client_fd;
/* Packet buffer for advertisement and responses */
struct ad_packet ad_packet_buffer; /* uint32_t alignment */
/* List of discovered hosts */
struct netplay_host_list discovered_hosts;
#ifdef HAVE_NETPLAYDISCOVERY
size_t discovered_hosts_allocated;
#endif
int room_count;
int reannounce;
unsigned server_port_deferred;
/* Packet buffer for advertisement and responses */
struct ad_packet ad_packet_buffer; /* uint32_t alignment */
int reping;
int latest_ping;
uint16_t mapping[RETROK_LAST];
char server_address_deferred[512];
unsigned server_port_deferred;
char server_address_deferred[256];
char server_session_deferred[32];
bool netplay_client_deferred;
/* Only used before init_netplay */
bool netplay_enabled;
bool netplay_is_client;
/* Used to avoid recursive netplay calls */
bool in_netplay;
bool netplay_client_deferred;
bool is_mitm;
bool has_set_netplay_mode;
bool has_set_netplay_ip_address;
bool has_set_netplay_ip_port;
@ -216,6 +256,8 @@ typedef struct
bool has_set_netplay_check_frames;
/* NAT traversal info (if NAT traversal is used and serving) */
struct nat_traversal_data nat_traversal_request;
/* Chat messages */
struct netplay_chat chat;
} net_driver_state_t;
net_driver_state_t *networking_state_get_ptr(void);
@ -246,6 +288,13 @@ void netplay_frontend_paused(netplay_t *netplay, bool paused);
*/
void netplay_toggle_play_spectate(netplay_t *netplay);
/**
* netplay_input_chat
*
* Opens an input menu for sending netplay chat
*/
void netplay_input_chat(netplay_t *netplay);
/**
* netplay_load_savestate
* @netplay : pointer to netplay object
@ -322,9 +371,9 @@ void deinit_netplay(void);
/**
* init_netplay
* @direct_host : Host to connect to directly, if applicable (client only)
* @server : server address to connect to (client only)
* @port : TCP port to host on/connect to
* @mitm_session : Session id for MITM/tunnel (client only).
*
* Initializes netplay.
*
@ -332,9 +381,9 @@ void deinit_netplay(void);
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool init_netplay(void *direct_host, const char *server, unsigned port);
bool init_netplay(const char *server, unsigned port, const char *mitm_session);
bool init_netplay_deferred(const char* server, unsigned port);
bool init_netplay_deferred(const char *server, unsigned port, const char *mitm_session);
void video_frame_net(const void *data, unsigned width,
unsigned height, size_t pitch);
@ -355,4 +404,8 @@ bool netplay_discovery_driver_ctl(
enum rarch_netplay_discovery_ctl_state state, void *data);
#endif
bool netplay_decode_hostname(const char *hostname,
char *address, unsigned *port, char *session, size_t len);
bool netplay_is_lan_address(struct sockaddr_in *addr);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2016-2017 - Gregor Richards
* Copyright (C) 2021-2021 - Roberto V. Rampim
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -27,12 +28,9 @@
#include "../../msg_hash.h"
#include "../../verbosity.h"
#define NETPLAY_PROTOCOL_VERSION 5
#define RARCH_DEFAULT_PORT 55435
#define RARCH_DEFAULT_NICK "Anonymous"
#define NETPLAY_NICK_LEN 32
#define NETPLAY_PASS_LEN 128
#define NETPLAY_PASS_HASH_LEN 64 /* length of a SHA-256 hash */
@ -174,7 +172,29 @@ enum netplay_cmd
/* CMD_CFG streamlines sending multiple
configurations. This acknowledges
each one individually */
NETPLAY_CMD_CFG_ACK = 0x0062
NETPLAY_CMD_CFG_ACK = 0x0062,
/* Chat commands */
/* Sends a player chat message.
* The server is responsible for formatting/truncating
* the message and relaying it to all playing clients,
* including the one that sent the message. */
NETPLAY_CMD_PLAYER_CHAT = 0x1000,
/* Ping commands */
/* Sends a ping command to the server/client.
* Intended for estimating the latency between these two peers. */
NETPLAY_CMD_PING_REQUEST = 0x1100,
NETPLAY_CMD_PING_RESPONSE = 0x1101,
/* Setting commands */
/* These host settings should be honored by the client,
* but they are not enforced. */
NETPLAY_CMD_SETTING_ALLOW_PAUSING = 0x2000,
NETPLAY_CMD_SETTING_INPUT_LATENCY_FRAMES = 0x2001
};
#define NETPLAY_CMD_SYNC_BIT_PAUSED (1U<<31)
@ -386,6 +406,20 @@ struct netplay_connection
/* Is this connection buffer in use? */
bool active;
/* Which netplay protocol is this connection running? */
uint32_t netplay_protocol;
/* Timer used to estimate a connection's latency */
retro_time_t ping_timer;
/* What latency is this connection running on?
* Network latency has limited precision as we estimate it
* once every pre-frame. */
int32_t ping;
/* Did we request a ping response? */
bool ping_requested;
};
/* Compression transcoder */
@ -397,6 +431,26 @@ struct compression_transcoder
void *decompression_stream;
};
typedef struct mitm_id
{
uint32_t magic;
uint8_t unique[12];
} mitm_id_t;
#define NETPLAY_MITM_MAX_PENDING 8
struct netplay_mitm_pending
{
int fds[NETPLAY_MITM_MAX_PENDING];
mitm_id_t ids[NETPLAY_MITM_MAX_PENDING];
retro_time_t timeouts[NETPLAY_MITM_MAX_PENDING];
mitm_id_t id_buf;
size_t id_recvd;
struct addrinfo *base_addr;
const struct addrinfo *addr;
};
struct netplay
{
/* When did we start falling behind? */
@ -530,6 +584,7 @@ struct netplay
/* TCP port (only set if serving) */
uint16_t tcp_port;
uint16_t ext_tcp_port;
/* The sharing mode for each device */
uint8_t device_share_modes[MAX_INPUT_DEVICES];
@ -593,6 +648,19 @@ struct netplay
/* Are we the connected? */
bool is_connected;
/* MITM session id */
mitm_id_t mitm_session_id;
/* MITM connection handler */
struct netplay_mitm_pending *mitm_pending;
/* Host settings */
int32_t input_latency_frames_min;
int32_t input_latency_frames_max;
bool allow_pausing;
/* Pseudo random seed */
unsigned long simple_rand_next;
};
/***************************************************************
@ -682,17 +750,6 @@ netplay_input_state_t netplay_input_state_for(
uint32_t netplay_expected_input_size(netplay_t *netplay,
uint32_t devices);
/***************************************************************
* NETPLAY-DISCOVERY.C
**************************************************************/
/**
* netplay_lan_ad_server
*
* Respond to any LAN ad queries that the netplay server has received.
*/
bool netplay_lan_ad_server(netplay_t *netplay);
/***************************************************************
* NETPLAY-FRONTEND.C
**************************************************************/
@ -715,7 +772,7 @@ void input_poll_net(void);
* part of the handshake protocol.
*/
bool netplay_handshake_init_send(netplay_t *netplay,
struct netplay_connection *connection);
struct netplay_connection *connection, uint32_t protocol);
/**
* netplay_handshake
@ -750,9 +807,10 @@ bool netplay_wait_and_init_serialization(netplay_t *netplay);
/**
* netplay_new:
* @direct_host : Netplay host discovered from scanning.
* @server : IP address of server.
* @mitm : IP address of the MITM/tunnel server.
* @port : Port of server.
* @mitm_session : Session id for MITM/tunnel.
* @stateless_mode : Shall we run in stateless mode?
* @check_frames : Frequency with which to check CRCs.
* @cb : Libretro callbacks.
@ -765,8 +823,8 @@ bool netplay_wait_and_init_serialization(netplay_t *netplay);
*
* Returns: new netplay data.
*/
netplay_t *netplay_new(void *direct_host,
const char *server, uint16_t port,
netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
const char *mitm_session,
bool stateless_mode, int check_frames,
const struct retro_callbacks *cb,
bool nat_traversal, const char *nick,
@ -913,10 +971,11 @@ bool netplay_resolve_input(netplay_t *netplay,
/**
* netplay_sync_pre_frame
* @netplay : pointer to netplay object
* @disconnect : disconnect netplay
*
* Pre-frame for Netplay synchronization.
*/
bool netplay_sync_pre_frame(netplay_t *netplay);
bool netplay_sync_pre_frame(netplay_t *netplay, bool *disconnect);
/**
* netplay_sync_post_frame

View File

@ -0,0 +1,27 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2016-2017 - Gregor Richards
* Copyright (C) 2021-2021 - Roberto V. Rampim
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __RARCH_NETPLAY_PROTOCOL_H
#define __RARCH_NETPLAY_PROTOCOL_H
#define LOW_NETPLAY_PROTOCOL_VERSION 5
#define HIGH_NETPLAY_PROTOCOL_VERSION 6
#define NETPLAY_PROTOCOL_VERSION HIGH_NETPLAY_PROTOCOL_VERSION
#endif

View File

@ -189,10 +189,6 @@ static bool netplay_json_object_member(void *ctx, const char *p_value,
{
p_ctx->cur_member_bool = &net_st->rooms_data->cur->has_spectate_password;
}
else if (string_is_equal(p_value, "fixed"))
{
p_ctx->cur_member_bool = &net_st->rooms_data->cur->fixed;
}
else if (string_is_equal(p_value, "mitm_ip"))
{
p_ctx->cur_member_string = net_st->rooms_data->cur->mitm_address;
@ -202,6 +198,11 @@ static bool netplay_json_object_member(void *ctx, const char *p_value,
{
p_ctx->cur_member_int = &net_st->rooms_data->cur->mitm_port;
}
else if (string_is_equal(p_value, "mitm_session"))
{
p_ctx->cur_member_string = net_st->rooms_data->cur->mitm_session;
p_ctx->cur_member_size = sizeof(net_st->rooms_data->cur->mitm_session);
}
else if (string_is_equal(p_value, "host_method"))
{
p_ctx->cur_member_int = &net_st->rooms_data->cur->host_method;

View File

@ -2613,6 +2613,12 @@ bool command_event(enum event_command cmd, void *data)
bool accessibility_enable = settings->bools.accessibility_enable;
unsigned accessibility_narrator_speech_speed = settings->uints.accessibility_narrator_speech_speed;
#endif
#ifdef HAVE_NETWORKING
if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL))
break;
#endif
boolean = runloop_st->paused;
boolean = !boolean;
@ -2639,11 +2645,21 @@ bool command_event(enum event_command cmd, void *data)
}
break;
case CMD_EVENT_UNPAUSE:
#ifdef HAVE_NETWORKING
if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL))
break;
#endif
boolean = false;
runloop_st->paused = boolean;
runloop_pause_checks();
break;
case CMD_EVENT_PAUSE:
#ifdef HAVE_NETWORKING
if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL))
break;
#endif
boolean = true;
runloop_st->paused = boolean;
runloop_pause_checks();
@ -2652,7 +2668,12 @@ bool command_event(enum event_command cmd, void *data)
#ifdef HAVE_MENU
if (menu_st->alive)
{
#ifdef HAVE_NETWORKING
bool menu_pause_libretro = settings->bools.menu_pause_libretro &&
netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL);
#else
bool menu_pause_libretro = settings->bools.menu_pause_libretro;
#endif
if (menu_pause_libretro)
command_event(CMD_EVENT_AUDIO_STOP, NULL);
else
@ -2660,16 +2681,32 @@ bool command_event(enum event_command cmd, void *data)
}
else
{
#ifdef HAVE_NETWORKING
bool menu_pause_libretro = settings->bools.menu_pause_libretro &&
netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL);
#else
bool menu_pause_libretro = settings->bools.menu_pause_libretro;
#endif
if (menu_pause_libretro)
command_event(CMD_EVENT_AUDIO_START, NULL);
}
#endif
break;
#ifdef HAVE_NETWORKING
case CMD_EVENT_NETPLAY_PING_TOGGLE:
settings->bools.netplay_ping_show =
!settings->bools.netplay_ping_show;
break;
case CMD_EVENT_NETPLAY_GAME_WATCH:
netplay_driver_ctl(RARCH_NETPLAY_CTL_GAME_WATCH, NULL);
break;
case CMD_EVENT_NETPLAY_PLAYER_CHAT:
netplay_driver_ctl(RARCH_NETPLAY_CTL_PLAYER_CHAT, NULL);
break;
case CMD_EVENT_NETPLAY_FADE_CHAT_TOGGLE:
settings->bools.netplay_fade_chat =
!settings->bools.netplay_fade_chat;
break;
case CMD_EVENT_NETPLAY_DEINIT:
deinit_netplay();
break;
@ -2679,71 +2716,40 @@ bool command_event(enum event_command cmd, void *data)
/* init netplay manually */
case CMD_EVENT_NETPLAY_INIT:
{
char *hostname = (char*)data;
char *netplay_server = NULL;
unsigned netplay_port = 0;
if (p_rarch->connect_host && !hostname)
{
struct string_list *addr_port = string_split(p_rarch->connect_host, "|");
if (addr_port && addr_port->size == 2)
{
char *tmp_netplay_server = addr_port->elems[0].data;
char *tmp_netplay_port = addr_port->elems[1].data;
if ( !string_is_empty(tmp_netplay_server)
&& !string_is_empty(tmp_netplay_port))
{
netplay_port = strtoul(tmp_netplay_port, NULL, 10);
if (netplay_port && netplay_port <= 0xFFFF)
{
netplay_server = strdup(tmp_netplay_server);
/* This way we free netplay_server
as well when done. */
free(p_rarch->connect_host);
p_rarch->connect_host = netplay_server;
}
}
}
string_list_free(addr_port);
}
if (!netplay_server || !netplay_port)
{
netplay_server = settings->paths.netplay_server;
netplay_port = settings->uints.netplay_port;
}
char tmp_netplay_server[256];
char tmp_netplay_session[sizeof(tmp_netplay_server)];
char *netplay_server = NULL;
char *netplay_session = NULL;
unsigned netplay_port = 0;
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
if (!init_netplay(
NULL,
hostname
? hostname
: netplay_server, netplay_port))
tmp_netplay_server[0] = '\0';
tmp_netplay_session[0] = '\0';
if (netplay_decode_hostname(p_rarch->connect_host,
tmp_netplay_server, &netplay_port, tmp_netplay_session,
sizeof(tmp_netplay_server)))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
if (p_rarch->connect_host)
{
free(p_rarch->connect_host);
p_rarch->connect_host = NULL;
}
return false;
netplay_server = tmp_netplay_server;
netplay_session = tmp_netplay_session;
}
if (p_rarch->connect_host)
{
free(p_rarch->connect_host);
p_rarch->connect_host = NULL;
}
if (string_is_empty(netplay_server))
netplay_server = settings->paths.netplay_server;
if (!netplay_port)
netplay_port = settings->uints.netplay_port;
if (!init_netplay(netplay_server, netplay_port, netplay_session))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
return false;
}
/* Disable rewind & SRAM autosave if it was enabled
* TODO/FIXME: Add a setting for these tweaks */
#ifdef HAVE_REWIND
@ -2757,34 +2763,29 @@ bool command_event(enum event_command cmd, void *data)
/* Initialize netplay via lobby when content is loaded */
case CMD_EVENT_NETPLAY_INIT_DIRECT:
{
/* buf is expected to be address|port */
static struct string_list *hostname = NULL;
char *buf = (char *)data;
unsigned netplay_port = settings->uints.netplay_port;
hostname = string_split(buf, "|");
char netplay_server[256];
char netplay_session[sizeof(netplay_server)];
unsigned netplay_port = 0;
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
RARCH_LOG("[Netplay]: Connecting to %s:%d (direct)\n",
hostname->elems[0].data, !string_is_empty(hostname->elems[1].data)
? atoi(hostname->elems[1].data)
: netplay_port);
netplay_server[0] = '\0';
netplay_session[0] = '\0';
netplay_decode_hostname((char*) data, netplay_server,
&netplay_port, netplay_session, sizeof(netplay_server));
if (!init_netplay(
NULL,
hostname->elems[0].data,
!string_is_empty(hostname->elems[1].data)
? atoi(hostname->elems[1].data)
: netplay_port))
if (!netplay_port)
netplay_port = settings->uints.netplay_port;
RARCH_LOG("[Netplay]: Connecting to %s|%d (direct)\n",
netplay_server, netplay_port);
if (!init_netplay(netplay_server, netplay_port, netplay_session))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
string_list_free(hostname);
return false;
}
string_list_free(hostname);
/* Disable rewind if it was enabled
TODO/FIXME: Add a setting for these tweaks */
#ifdef HAVE_REWIND
@ -2798,33 +2799,29 @@ bool command_event(enum event_command cmd, void *data)
/* init netplay via lobby when content is not loaded */
case CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED:
{
static struct string_list *hostname = NULL;
/* buf is expected to be address|port */
char *buf = (char *)data;
unsigned netplay_port = settings->uints.netplay_port;
hostname = string_split(buf, "|");
char netplay_server[256];
char netplay_session[sizeof(netplay_server)];
unsigned netplay_port = 0;
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
RARCH_LOG("[Netplay]: Connecting to %s:%d (deferred)\n",
hostname->elems[0].data, !string_is_empty(hostname->elems[1].data)
? atoi(hostname->elems[1].data)
: netplay_port);
netplay_server[0] = '\0';
netplay_session[0] = '\0';
netplay_decode_hostname((char*) data, netplay_server,
&netplay_port, netplay_session, sizeof(netplay_server));
if (!init_netplay_deferred(
hostname->elems[0].data,
!string_is_empty(hostname->elems[1].data)
? atoi(hostname->elems[1].data)
: netplay_port))
if (!netplay_port)
netplay_port = settings->uints.netplay_port;
RARCH_LOG("[Netplay]: Connecting to %s|%d (deferred)\n",
netplay_server, netplay_port);
if (!init_netplay_deferred(netplay_server, netplay_port, netplay_session))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
string_list_free(hostname);
return false;
}
string_list_free(hostname);
/* Disable rewind if it was enabled
* TODO/FIXME: Add a setting for these tweaks */
#ifdef HAVE_REWIND
@ -2838,8 +2835,8 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_NETPLAY_ENABLE_HOST:
{
#ifdef HAVE_MENU
bool contentless = false;
bool is_inited = false;
bool contentless = false;
bool is_inited = false;
content_get_status(&contentless, &is_inited);
@ -2905,7 +2902,10 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_NETPLAY_HOST_TOGGLE:
case CMD_EVENT_NETPLAY_DISCONNECT:
case CMD_EVENT_NETPLAY_ENABLE_HOST:
case CMD_EVENT_NETPLAY_PING_TOGGLE:
case CMD_EVENT_NETPLAY_GAME_WATCH:
case CMD_EVENT_NETPLAY_PLAYER_CHAT:
case CMD_EVENT_NETPLAY_FADE_CHAT_TOGGLE:
return false;
#endif
case CMD_EVENT_FULLSCREEN_TOGGLE:

View File

@ -3095,7 +3095,13 @@ bool runloop_environment_cb(unsigned cmd, void *data)
#ifdef HAVE_MENU
menu_opened = menu_state_get_ptr()->alive;
if (menu_opened)
#ifdef HAVE_NETWORKING
core_paused = settings->bools.menu_pause_libretro &&
netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL);
#else
core_paused = settings->bools.menu_pause_libretro;
#endif
#endif
if (core_paused)
@ -6590,8 +6596,15 @@ static enum runloop_state_enum runloop_check_state(
action = (enum menu_action)menu_event(
settings,
&current_bits, &trigger_input, display_kb);
focused = pause_nonactive ? is_focused : true;
focused = focused && !uico_st->is_on_foreground;
#ifdef HAVE_NETWORKING
if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL))
focused = true;
else
#endif
{
focused = pause_nonactive ? is_focused : true;
focused = focused && !uico_st->is_on_foreground;
}
if (action == old_action)
{
@ -6681,7 +6694,12 @@ static enum runloop_state_enum runloop_check_state(
if (focused || !runloop_st->idle)
{
bool runloop_is_inited = runloop_st->is_inited;
#ifdef HAVE_NETWORKING
bool menu_pause_libretro = settings->bools.menu_pause_libretro &&
netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL);
#else
bool menu_pause_libretro = settings->bools.menu_pause_libretro;
#endif
bool libretro_running = !menu_pause_libretro
&& runloop_is_inited
&& (runloop_st->current_core_type != CORE_TYPE_DUMMY);
@ -6824,6 +6842,9 @@ static enum runloop_state_enum runloop_check_state(
}
#endif
#ifdef HAVE_NETWORKING
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL))
#endif
if (pause_nonactive)
focused = is_focused;
@ -6857,7 +6878,10 @@ static enum runloop_state_enum runloop_check_state(
#ifdef HAVE_NETWORKING
/* Check Netplay */
HOTKEY_CHECK(RARCH_NETPLAY_PING_TOGGLE, CMD_EVENT_NETPLAY_PING_TOGGLE, true, NULL);
HOTKEY_CHECK(RARCH_NETPLAY_GAME_WATCH, CMD_EVENT_NETPLAY_GAME_WATCH, true, NULL);
HOTKEY_CHECK(RARCH_NETPLAY_PLAYER_CHAT, CMD_EVENT_NETPLAY_PLAYER_CHAT, true, NULL);
HOTKEY_CHECK(RARCH_NETPLAY_FADE_CHAT_TOGGLE, CMD_EVENT_NETPLAY_FADE_CHAT_TOGGLE, true, NULL);
#endif
/* Check if we have pressed the pause button */
@ -7302,7 +7326,12 @@ int runloop_iterate(void)
unsigned max_users = settings->uints.input_max_users;
retro_time_t current_time = cpu_features_get_time_usec();
#ifdef HAVE_MENU
#ifdef HAVE_NETWORKING
bool menu_pause_libretro = settings->bools.menu_pause_libretro &&
netplay_driver_ctl(RARCH_NETPLAY_CTL_ALLOW_PAUSE, NULL);
#else
bool menu_pause_libretro = settings->bools.menu_pause_libretro;
#endif
bool core_paused = runloop_st->paused || (menu_pause_libretro && menu_state_get_ptr()->alive);
#else
bool core_paused = runloop_st->paused;

View File

@ -55,7 +55,6 @@ bool task_push_netplay_lan_scan(retro_task_callback_t cb)
task->type = TASK_TYPE_BLOCKING;
task->handler = task_netplay_lan_scan_handler;
task->callback = cb;
task->title = strdup(msg_hash_to_str(MSG_NETPLAY_LAN_SCANNING));
task_queue_push(task);

View File

@ -412,12 +412,14 @@ QWidget *NetplayPage::widget()
checksLayout->add(MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE);
checksLayout->add(MENU_ENUM_LABEL_NETPLAY_START_AS_SPECTATOR);
checksLayout->add(MENU_ENUM_LABEL_NETPLAY_FADE_CHAT);
checksLayout->add(MENU_ENUM_LABEL_NETPLAY_ALLOW_PAUSING);
checksLayout->add(MENU_ENUM_LABEL_NETWORK_ON_DEMAND_THUMBNAILS);
serverForm->add(MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS);
serverForm->add(MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT);
serverForm->add(MENU_ENUM_LABEL_NETPLAY_MAX_CONNECTIONS);
serverForm->add(MENU_ENUM_LABEL_NETPLAY_MAX_PING);
serverForm->add(MENU_ENUM_LABEL_NETPLAY_PASSWORD);
serverForm->add(MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD);
serverForm->add(MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL);
@ -561,6 +563,7 @@ QWidget *NotificationsPage::widget()
notificationsGroup->add(MENU_ENUM_LABEL_MEMORY_SHOW);
notificationsGroup->add(MENU_ENUM_LABEL_MEMORY_UPDATE_INTERVAL);
notificationsGroup->add(MENU_ENUM_LABEL_STATISTICS_SHOW);
notificationsGroup->add(MENU_ENUM_LABEL_NETPLAY_PING_SHOW);
notificationsGroup->add(MENU_ENUM_LABEL_VIDEO_FONT_PATH);
notificationsGroup->add(MENU_ENUM_LABEL_VIDEO_FONT_SIZE);
notificationsGroup->add(MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X);