diff --git a/CHANGES.md b/CHANGES.md index f57d0eb6bc..13b54d8668 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -34,7 +34,8 @@ - LOCALIZATION: Update Japanese translation. - LOCALIZATION: Update Portuguese-Brazilian translation. - LOCALIZATION: Update Spanish translation. -- OSX: Modify HID buttons detection algorithm. +- NETPLAY: Add menu option to select different MITM (relay) server locations. +- OSX: Modify HID buttons detection algorithm. - SOLARIS: Initial port. - SWITCH: Initial Nintendo Switch port, based on libtransistor SDK. - PS3: Enable Cheevos. diff --git a/config.def.h b/config.def.h index 529b282ffa..2f11287444 100644 --- a/config.def.h +++ b/config.def.h @@ -551,6 +551,8 @@ static const int netplay_check_frames = 600; static const bool netplay_use_mitm_server = false; +static const char *netplay_mitm_server = "nyc"; + #ifdef HAVE_NETWORKING static const unsigned netplay_share_digital = RARCH_NETPLAY_SHARE_DIGITAL_NO_PREFERENCE; diff --git a/configuration.c b/configuration.c index e7a8cae859..6193363d11 100644 --- a/configuration.c +++ b/configuration.c @@ -1036,6 +1036,7 @@ static struct config_array_setting *populate_settings_array(settings_t *settings SETTING_ARRAY("bundle_assets_dst_path", settings->arrays.bundle_assets_dst, false, NULL, true); SETTING_ARRAY("bundle_assets_dst_path_subdir", settings->arrays.bundle_assets_dst_subdir, false, NULL, true); SETTING_ARRAY("led_driver", settings->arrays.led_driver, false, NULL, true); + SETTING_ARRAY("netplay_mitm_server", settings->arrays.netplay_mitm_server, false, NULL, true); *size = count; return tmp; @@ -1551,6 +1552,7 @@ static void config_set_defaults(void) const char *def_led = config_get_default_led(); const char *def_location = config_get_default_location(); const char *def_record = config_get_default_record(); + const char *def_mitm = netplay_mitm_server; struct config_float_setting *float_settings = populate_settings_float (settings, &float_settings_size); struct config_bool_setting *bool_settings = populate_settings_bool (settings, &bool_settings_size); struct config_int_setting *int_settings = populate_settings_int (settings, &int_settings_size); @@ -1630,6 +1632,9 @@ static void config_set_defaults(void) if (def_record) strlcpy(settings->arrays.record_driver, def_record, sizeof(settings->arrays.record_driver)); + if (def_mitm) + strlcpy(settings->arrays.netplay_mitm_server, + def_mitm, sizeof(settings->arrays.netplay_mitm_server)); #ifdef HAVE_MENU if (def_menu) strlcpy(settings->arrays.menu_driver, diff --git a/configuration.h b/configuration.h index 21c7b75e99..9223a210b3 100644 --- a/configuration.h +++ b/configuration.h @@ -408,6 +408,8 @@ typedef struct settings char bundle_assets_src[PATH_MAX_LENGTH]; char bundle_assets_dst[PATH_MAX_LENGTH]; char bundle_assets_dst_subdir[PATH_MAX_LENGTH]; + + char netplay_mitm_server[255]; } arrays; struct diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 0fce42a8db..1eabc2694b 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3041,6 +3041,8 @@ MSG_HASH( ) MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, "MITMサーバーを使用") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, + "MITMサーバーの設置場所") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, "中間者のサーバーにネットプレイ接続を転送する。ファイアウォールやNAT/UPnPが問題の時に便利。") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index dcd7b57f17..28e4c248e2 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1295,6 +1295,8 @@ MSG_HASH(MENU_ENUM_LABEL_SHADER_PIPELINE_BOKEH, "shader_pipeline_bokeh") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER, "netplay_use_mitm_server") +MSG_HASH(MENU_ENUM_LABEL_NETPLAY_MITM_SERVER, + "netplay_mitm_server") MSG_HASH(MENU_ENUM_LABEL_ADD_TO_MIXER, "audio_add_to_mixer") MSG_HASH(MENU_ENUM_LABEL_ADD_TO_MIXER_AND_COLLECTION, diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index f28500cecd..a215541dc9 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1655,9 +1655,15 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER: snprintf(s, len, - "When hosting, relay connection through a\n" - "man-in-the-middle server\n" - "to get around firewalls or NAT/UPnP issues.\n"); + "When hosting a netplay session, relay connection through a \n" + "man-in-the-middle server \n" + "to get around firewalls or NAT/UPnP issues. \n"); + break; + case MENU_ENUM_LABEL_NETPLAY_MITM_SERVER: + snprintf(s, len, + "Specifies the man-in-the-middle server \n" + "to use for netplay. A server that is \n" + "located closer to you may have less latency. \n"); break; case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES: snprintf(s, len, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index fddbe1b808..4cb8c174a8 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3185,6 +3185,10 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_USE_MITM_SERVER, "Use Relay Server") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER, "Forward netplay connections through a man-in-the-middle server. Useful if the host is behind a firewall or has NAT/UPnP problems.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, + "Relay Server Location") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER, + "Choose a specific relay server to use. Geographically closer locations tend to have lower latency.") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER, "Add to mixer") MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TO_MIXER_AND_COLLECTION, diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index e7c7977033..cbf73cca84 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -309,6 +309,36 @@ static void menu_action_setting_disp_set_label_pipeline( } +static void menu_action_setting_disp_set_label_netplay_mitm_server( + file_list_t* list, + unsigned *w, unsigned type, unsigned i, + const char *label, + char *s, size_t len, + const char *entry_label, + const char *path, + char *s2, size_t len2) +{ + settings_t *settings = config_get_ptr(); + + *s = '\0'; + *w = 19; + strlcpy(s2, path, len2); + + if (!settings) + return; + + if (!string_is_empty(settings->arrays.netplay_mitm_server)) + { + unsigned i; + + for (i = 0; i < ARRAY_SIZE(netplay_mitm_server_list); i++) + { + if (string_is_equal(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[i].name)) + strlcpy(s, netplay_mitm_server_list[i].description, len); + } + } +} + static void menu_action_setting_disp_set_label_shader_watch_for_changes( file_list_t* list, unsigned *w, unsigned type, unsigned i, @@ -2170,27 +2200,6 @@ int menu_cbs_init_bind_get_string_representation(menu_file_list_cbs_t *cbs, RARCH_LOG("MENU_SETTINGS_LAST: %d\n", MENU_SETTINGS_LAST); #endif - if (cbs->setting) - { - switch (setting_get_type(cbs->setting)) - { - case ST_BOOL: - BIND_ACTION_GET_VALUE(cbs, - menu_action_setting_disp_set_label_setting_bool); - return 0; - case ST_STRING: - BIND_ACTION_GET_VALUE(cbs, - menu_action_setting_disp_set_label_setting_string); - return 0; - case ST_PATH: - BIND_ACTION_GET_VALUE(cbs, - menu_action_setting_disp_set_label_setting_path); - return 0; - default: - break; - } - } - if (cbs->enum_idx != MSG_UNKNOWN) { switch (cbs->enum_idx) @@ -2220,6 +2229,31 @@ int menu_cbs_init_bind_get_string_representation(menu_file_list_cbs_t *cbs, BIND_ACTION_GET_VALUE(cbs, menu_action_setting_disp_set_label_achievement_information); return 0; + case MENU_ENUM_LABEL_NETPLAY_MITM_SERVER: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_netplay_mitm_server); + return 0; + default: + break; + } + } + + if (cbs->setting) + { + switch (setting_get_type(cbs->setting)) + { + case ST_BOOL: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_setting_bool); + return 0; + case ST_STRING: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_setting_string); + return 0; + case ST_PATH: + BIND_ACTION_GET_VALUE(cbs, + menu_action_setting_disp_set_label_setting_path); + return 0; default: break; } diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index 8faa386e2b..9453af6f02 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -37,6 +37,7 @@ #include "../../managers/cheat_manager.h" #include "../../file_path_special.h" #include "../../retroarch.h" +#include "../../network/netplay/netplay.h" #ifndef BIND_ACTION_LEFT #define BIND_ACTION_LEFT(cbs, name) \ @@ -324,6 +325,44 @@ static int action_left_shader_num_passes(unsigned type, const char *label, return 0; } +static int action_left_netplay_mitm_server(unsigned type, const char *label, + bool wraparound) +{ + settings_t *settings = config_get_ptr(); + int i; + bool found = false; + int list_len = ARRAY_SIZE(netplay_mitm_server_list); + + for (i = 0; i < list_len; i++) + { + /* find the currently selected server in the list */ + if (string_is_equal(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[i].name)) + { + /* move to the previous one in the list, wrap around if necessary */ + if (i - 1 >= 0) + { + found = true; + strlcpy(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[i - 1].name, sizeof(settings->arrays.netplay_mitm_server)); + break; + } + else if (wraparound) + { + found = true; + strlcpy(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[list_len - 1].name, sizeof(settings->arrays.netplay_mitm_server)); + break; + } + } + } + + if (!found) + { + /* current entry was invalid, go back to the end */ + strlcpy(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[list_len - 1].name, sizeof(settings->arrays.netplay_mitm_server)); + } + + return 0; +} + static int action_left_shader_watch_for_changes(unsigned type, const char *label, bool wraparound) { @@ -490,6 +529,9 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_SHADER_DEFAULT_FILTER: BIND_ACTION_LEFT(cbs, action_left_shader_filter_default); break; + case MENU_ENUM_LABEL_NETPLAY_MITM_SERVER: + BIND_ACTION_LEFT(cbs, action_left_netplay_mitm_server); + break; case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES: BIND_ACTION_LEFT(cbs, action_left_shader_watch_for_changes); break; diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index 2f4fe0efcc..f5bbc5af20 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -39,6 +39,7 @@ #include "../../retroarch.h" #include "../../verbosity.h" #include "../../ui/ui_companion_driver.h" +#include "../../network/netplay/netplay.h" #ifndef BIND_ACTION_RIGHT #define BIND_ACTION_RIGHT(cbs, name) \ @@ -327,6 +328,44 @@ static int action_right_shader_num_passes(unsigned type, const char *label, return 0; } +static int action_right_netplay_mitm_server(unsigned type, const char *label, + bool wraparound) +{ + settings_t *settings = config_get_ptr(); + unsigned i; + bool found = false; + unsigned list_len = ARRAY_SIZE(netplay_mitm_server_list); + + for (i = 0; i < list_len; i++) + { + /* find the currently selected server in the list */ + if (string_is_equal(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[i].name)) + { + /* move to the next one in the list, wrap around if necessary */ + if (i + 1 < list_len) + { + found = true; + strlcpy(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[i + 1].name, sizeof(settings->arrays.netplay_mitm_server)); + break; + } + else if (wraparound) + { + found = true; + strlcpy(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[0].name, sizeof(settings->arrays.netplay_mitm_server)); + break; + } + } + } + + if (!found) + { + /* current entry was invalid, go back to the start */ + strlcpy(settings->arrays.netplay_mitm_server, netplay_mitm_server_list[0].name, sizeof(settings->arrays.netplay_mitm_server)); + } + + return 0; +} + static int action_right_shader_watch_for_changes(unsigned type, const char *label, bool wraparound) { @@ -600,6 +639,9 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_SHADER_DEFAULT_FILTER: BIND_ACTION_RIGHT(cbs, action_right_shader_filter_default); break; + case MENU_ENUM_LABEL_NETPLAY_MITM_SERVER: + BIND_ACTION_RIGHT(cbs, action_right_netplay_mitm_server); + break; case MENU_ENUM_LABEL_SHADER_WATCH_FOR_CHANGES: BIND_ACTION_RIGHT(cbs, action_right_shader_watch_for_changes); break; diff --git a/menu/cbs/menu_cbs_start.c b/menu/cbs/menu_cbs_start.c index 377c84294e..84f028c2ce 100644 --- a/menu/cbs/menu_cbs_start.c +++ b/menu/cbs/menu_cbs_start.c @@ -168,6 +168,13 @@ static int action_start_shader_filter_pass(unsigned type, const char *label) return menu_shader_manager_clear_pass_filter(pass); } +static int action_start_netplay_mitm_server(unsigned type, const char *label) +{ + settings_t *settings = config_get_ptr(); + strlcpy(settings->arrays.netplay_mitm_server, netplay_mitm_server, sizeof(settings->arrays.netplay_mitm_server)); + return 0; +} + static int action_start_shader_watch_for_changes(unsigned type, const char *label) { settings_t *settings = config_get_ptr(); @@ -299,6 +306,10 @@ static int menu_cbs_init_bind_start_compare_label(menu_file_list_cbs_t *cbs) break; case MENU_ENUM_LABEL_SCREEN_RESOLUTION: BIND_ACTION_START(cbs, action_start_video_resolution); + break; + case MENU_ENUM_LABEL_NETPLAY_MITM_SERVER: + BIND_ACTION_START(cbs, action_start_netplay_mitm_server); + break; default: return -1; } diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 003aacea12..e1f01dffe3 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -373,6 +373,7 @@ default_sublabel_macro(action_bind_sublabel_video_viewport_custom_width, default_sublabel_macro(action_bind_sublabel_video_viewport_custom_x, MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X) default_sublabel_macro(action_bind_sublabel_video_viewport_custom_y, MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y) default_sublabel_macro(action_bind_sublabel_netplay_use_mitm_server, MENU_ENUM_SUBLABEL_NETPLAY_USE_MITM_SERVER) +default_sublabel_macro(action_bind_sublabel_netplay_mitm_server, MENU_ENUM_SUBLABEL_NETPLAY_MITM_SERVER) default_sublabel_macro(action_bind_sublabel_core_delete, MENU_ENUM_SUBLABEL_CORE_DELETE) static int action_bind_sublabel_cheevos_entry( @@ -1472,6 +1473,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_use_mitm_server); break; + case MENU_ENUM_LABEL_NETPLAY_MITM_SERVER: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_mitm_server); + break; case MENU_ENUM_LABEL_CORE_DELETE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_delete); default: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index faa141220a..1f7570b274 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5498,6 +5498,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER, PARSE_ONLY_BOOL, false) != -1) count++; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY_MITM_SERVER, + PARSE_ONLY_STRING, false) != -1) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS, PARSE_ONLY_STRING, false) != -1) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 02f802cb9b..356ac85fe8 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -575,6 +575,12 @@ static void setting_get_string_representation_uint_autosave_interval(void *data, } #endif +static void setting_get_string_representation_netplay_mitm_server(void *data, + char *s, size_t len) +{ + +} + #ifdef HAVE_LANGEXTRA static void setting_get_string_representation_uint_user_language(void *data, char *s, size_t len) @@ -6719,6 +6725,21 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); + CONFIG_STRING( + list, list_info, + settings->arrays.netplay_mitm_server, + sizeof(settings->arrays.netplay_mitm_server), + MENU_ENUM_LABEL_NETPLAY_MITM_SERVER, + MENU_ENUM_LABEL_VALUE_NETPLAY_MITM_SERVER, + netplay_mitm_server, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].get_string_representation = + &setting_get_string_representation_netplay_mitm_server; + CONFIG_STRING( list, list_info, settings->paths.netplay_server, diff --git a/msg_hash.h b/msg_hash.h index 21bdc4ceac..91673d48f3 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1729,6 +1729,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, MENU_LABEL(NETPLAY_USE_MITM_SERVER), + MENU_LABEL(NETPLAY_MITM_SERVER), MSG_LAST }; diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index 712f66dc27..535eb2ebe5 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -29,6 +29,16 @@ typedef struct netplay netplay_t; +typedef struct mitm_server { + const char *name; + const char *description; +} mitm_server_t; + +static const mitm_server_t netplay_mitm_server_list[] = { + { "nyc", "New York City, USA" }, + { "madrid", "Madrid, Spain" }, +}; + enum rarch_netplay_ctl_state { RARCH_NETPLAY_CTL_NONE = 0, diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 9515fec3c3..cd1aaf0994 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -778,10 +778,11 @@ static void netplay_announce(void) buf[0] = '\0'; snprintf(buf, sizeof(buf), "username=%s&core_name=%s&core_version=%s&" - "game_name=%s&game_crc=%08X&port=%d" + "game_name=%s&game_crc=%08X&port=%d&mitm_server=%s" "&has_password=%d&has_spectate_password=%d&force_mitm=%d&retroarch_version=%s&frontend=%s", username, corename, coreversion, gamename, content_crc, settings->uints.netplay_port, + settings->arrays.netplay_mitm_server, *settings->paths.netplay_password ? 1 : 0, *settings->paths.netplay_spectate_password ? 1 : 0, settings->bools.netplay_use_mitm_server, diff --git a/retroarch.cfg b/retroarch.cfg index 9319490de6..19a0d18b75 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -774,6 +774,9 @@ video_message_bgcolor_opacity = 1.0 # Force game hosting to go through a man-in-the-middle server to get around firewalls and NAT/UPnP problems. # netplay_use_mitm_server = false +# The requested MITM server to use. +# netplay_mitm_server = "nyc" + #### Misc # Enable rewinding. This will take a performance hit when playing, so it is disabled by default.