Merge pull request #4436 from fr500/lobby

Basic lobby system (don't merge, just for tracking)
This commit is contained in:
Twinaphex 2017-01-22 21:08:43 +01:00 committed by GitHub
commit 3ff158b907
23 changed files with 601 additions and 15 deletions

View File

@ -1165,7 +1165,8 @@ ifeq ($(HAVE_NETWORKING), 1)
network/net_http_special.o \
tasks/task_http.o \
tasks/task_netplay_lan_scan.o \
tasks/task_wifi.o
tasks/task_wifi.o \
tasks/task_netplay_crc.o
ifneq ($(HAVE_SOCKET_LEGACY),1)
OBJ += $(LIBRETRO_COMM_DIR)/net/net_ifinfo.o

View File

@ -2449,6 +2449,24 @@ bool command_event(enum event_command cmd, void *data)
}
}
break;
case CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED:
{
/* buf is expected to be address:port, there must be a better way
to do this but for now I'll just use a string list */
char *buf = (char *) data;
static struct string_list *hostname = NULL;
hostname = string_split(buf, ":");
settings_t *settings = config_get_ptr();
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
if (!init_netplay_deferred(
hostname->elems[0].data, atoi(hostname->elems[1].data)))
{
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
return false;
}
}
break;
case CMD_EVENT_NETPLAY_FLIP_PLAYERS:
netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL);
break;
@ -2461,6 +2479,7 @@ bool command_event(enum event_command cmd, void *data)
case CMD_EVENT_NETWORK_INIT:
case CMD_EVENT_NETPLAY_INIT:
case CMD_EVENT_NETPLAY_INIT_DIRECT:
case CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED:
case CMD_EVENT_NETPLAY_FLIP_PLAYERS:
case CMD_EVENT_NETPLAY_GAME_WATCH:
return false;

View File

@ -171,6 +171,8 @@ enum event_command
CMD_EVENT_NETPLAY_INIT,
/* Initializes netplay system with a direct host specified. */
CMD_EVENT_NETPLAY_INIT_DIRECT,
/* Initializes netplay system with a direct host specified after loading content. */
CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
/* Deinitializes netplay system. */
CMD_EVENT_NETPLAY_DEINIT,
/* Flip netplay players. */

View File

@ -53,6 +53,7 @@ enum file_path_enum
FILE_PATH_LAKKA_URL,
FILE_PATH_CORE_THUMBNAILS_URL,
FILE_PATH_INDEX_DIRS_URL,
FILE_PATH_NETPLAY_ROOM_LIST_URL,
FILE_PATH_INDEX_URL,
FILE_PATH_INDEX_EXTENDED_URL,
FILE_PATH_CGP_EXTENSION,

View File

@ -101,6 +101,8 @@ const char *file_path_str(enum file_path_enum enum_idx)
return ".index-dirs";
case FILE_PATH_INDEX_EXTENDED_URL:
return ".index-extended";
case FILE_PATH_NETPLAY_ROOM_LIST_URL:
return "registry.lpl";
case FILE_PATH_CORE_THUMBNAILS_URL:
return "http://thumbnailpacks.libretro.com";
case FILE_PATH_LAKKA_URL:

View File

@ -910,6 +910,7 @@ NETPLAY
#include "../tasks/task_http.c"
#include "../tasks/task_netplay_lan_scan.c"
#include "../tasks/task_wifi.c"
#include "../tasks/task_netplay_crc.c"
#endif
/*============================================================

View File

@ -14,6 +14,8 @@ MSG_HASH(MENU_ENUM_LABEL_CONFIGURATIONS_LIST,
"configurations_list")
MSG_HASH(MENU_ENUM_LABEL_ADD_TAB,
"add_tab")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_TAB,
"netplay_tab")
MSG_HASH(MENU_ENUM_LABEL_ARCHIVE_MODE,
"archive_mode")
MSG_HASH(MENU_ENUM_LABEL_ASSETS_DIRECTORY,
@ -155,6 +157,8 @@ MSG_HASH(MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT,
"config_save_on_exit")
MSG_HASH(MENU_ENUM_LABEL_CONNECT_WIFI,
"connect_wifi")
MSG_HASH(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
"connect_room")
MSG_HASH(MENU_ENUM_LABEL_CONTENT_ACTIONS,
"content_actions")
MSG_HASH(MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST,
@ -837,6 +841,8 @@ MSG_HASH(MENU_ENUM_LABEL_SCAN_DIRECTORY,
"scan_directory")
MSG_HASH(MENU_ENUM_LABEL_SCAN_FILE,
"scan_file")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS,
"refresh_rooms")
MSG_HASH(MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY,
"scan_this_directory")
MSG_HASH(MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY,

View File

@ -199,6 +199,10 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_ADD_TAB,
"Import content"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_TAB,
"Netplay Rooms"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_ARCHIVE_MODE,
"Archive File Association Action"
@ -967,13 +971,13 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay Delay Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
"Disconnect")
"Disconnect from netplay host")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE,
"Netplay Enable")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT,
"Connect to Netplay host")
"Connect to netplay host")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST,
"Start hosting")
"Start netplay host")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS,
"Server Address")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS,

View File

@ -487,6 +487,7 @@ static int menu_cbs_init_bind_left_compare_label(menu_file_list_cbs_t *cbs,
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_TAB)) ||
@ -586,6 +587,7 @@ static int menu_cbs_init_bind_left_compare_type(menu_file_list_cbs_t *cbs,
if ( string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_TAB)) ||
@ -625,6 +627,7 @@ int menu_cbs_init_bind_left(menu_file_list_cbs_t *cbs,
if ( string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB)) ||

View File

@ -3117,6 +3117,44 @@ static int action_ok_netplay_lan_scan_list(const char *path,
entry_idx, ACTION_OK_DL_NETPLAY_LAN_SCAN_SETTINGS_LIST);
}
static int action_ok_netplay_connect_room(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
#ifdef HAVE_NETWORKING
settings_t *settings = config_get_ptr();
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
char tmp_hostname[512];
/* For testing purposes
strlcpy(tmp_hostname, "192.168.1.241", sizeof(tmp_hostname));*/
strlcpy(tmp_hostname, netplay_room_list[idx - 1].address, sizeof(tmp_hostname));
snprintf(tmp_hostname, sizeof(tmp_hostname), "%s:%d",
netplay_room_list[idx - 1].address, netplay_room_list[idx - 1].port);
RARCH_LOG("%s %s %08x", netplay_room_list[idx - 1].address, netplay_room_list[idx - 1].gamename, netplay_room_list[idx - 1].gamecrc);
/* If we haven't yet started, this will load on its own */
if (!content_is_inited())
{
task_push_netplay_crc_scan(netplay_room_list[idx - 1].gamecrc,
tmp_hostname, netplay_room_list[idx - 1].corename);
}
else
{
/* Enable Netplay itself */
if (!command_event(CMD_EVENT_NETPLAY_INIT, (void *) tmp_hostname))
return -1;
}
#else
return -1;
#endif
return 0;
}
static int action_ok_lakka_services(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
@ -3264,6 +3302,8 @@ static int action_ok_push_content_list(const char *path,
entry_idx, ACTION_OK_DL_CONTENT_LIST);
}
static int action_ok_push_scan_file(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
@ -3271,6 +3311,126 @@ static int action_ok_push_scan_file(const char *path,
return action_ok_push_content_list(path, label, type, idx, entry_idx);
}
static void netplay_refresh_rooms_cb(void *task_data, void *user_data, const char *err)
{
char buf[PATH_MAX_LENGTH];
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
menu_file_transfer_t *state = (menu_file_transfer_t*)user_data;
buf[0] = '\0';
if (!data || err)
goto finish;
memcpy(buf, data->data, data->len * sizeof(char));
buf[data->len] = '\0';
finish:
if (!err && !strstr(buf, file_path_str(FILE_PATH_NETPLAY_ROOM_LIST_URL)))
{
if (string_is_empty(buf))
{
netplay_room_count = 0;
RARCH_LOG("Room list empty\n");
}
else
{
int i, j = 0;
char tmp[PATH_MAX_LENGTH];
static struct string_list *room_data = NULL;
file_list_t *file_list = NULL;
file_list = menu_entries_get_selection_buf_ptr(0);
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list);
room_data = string_split(buf, "\n");
if (netplay_room_list)
free(netplay_room_list);
netplay_room_count = room_data->size / 8;
netplay_room_list = (struct netplay_room*)malloc(sizeof(struct netplay_room) * netplay_room_count);
/*for (int i = 0; i < room_data->size; i++)
{
strlcpy(tmp,
room_data->elems[i].data, sizeof(tmp));
RARCH_LOG("tmp %s\n", tmp);
}*/
menu_entries_append_enum(file_list,
"Refresh Room List",
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS),
MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS,
MENU_SETTING_ACTION, 0, 0);
RARCH_LOG ("Found %d rooms\n", netplay_room_count);
for (i = 0; i < netplay_room_count; i++)
{
strlcpy(netplay_room_list[i].nickname, room_data->elems[j + 0].data, sizeof(netplay_room_list[i].nickname));
strlcpy(netplay_room_list[i].address, room_data->elems[j + 1].data, sizeof(netplay_room_list[i].address));
strlcpy(netplay_room_list[i].corename, room_data->elems[j + 3].data, sizeof(netplay_room_list[i].corename));
strlcpy(netplay_room_list[i].coreversion, room_data->elems[j + 4].data, sizeof(netplay_room_list[i].coreversion));
strlcpy(netplay_room_list[i].gamename, room_data->elems[j + 5].data, sizeof(netplay_room_list[i].coreversion));
netplay_room_list[i].port = atoi(room_data->elems[j + 2].data);
netplay_room_list[i].gamecrc = atoi(room_data->elems[j + 6].data);
netplay_room_list[i].timestamp = atoi(room_data->elems[j + 7].data);
RARCH_LOG("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,
netplay_room_list[i].nickname,
netplay_room_list[i].address,
netplay_room_list[i].port,
netplay_room_list[i].corename,
netplay_room_list[i].coreversion,
netplay_room_list[i].gamename,
netplay_room_list[i].gamecrc,
netplay_room_list[i].timestamp);
j+=8;
char s[PATH_MAX_LENGTH];
snprintf(s, sizeof(s), "Nickname: %s", netplay_room_list[i].nickname);
menu_entries_append_enum(file_list,
s,
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM),
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
MENU_WIFI, 0, 0);
}
}
}
if (err)
RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), err);
if (data)
{
if (data->data)
free(data->data);
free(data);
}
if (user_data)
free(user_data);
}
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/raw/";
task_push_http_transfer(url, true, NULL, netplay_refresh_rooms_cb, NULL);
return 0;
}
static int action_ok_scan_directory_list(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
@ -3781,7 +3941,7 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
first_char = atoi(&str[0]);
if (first_char != (i+1))
if (first_char != ((i+1)))
continue;
BIND_ACTION_OK(cbs, action_ok_push_user_binds_list);
@ -3994,6 +4154,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_SCAN_FILE:
BIND_ACTION_OK(cbs, action_ok_push_scan_file);
break;
case MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS:
BIND_ACTION_OK(cbs, action_ok_push_netplay_refresh_rooms);
break;
case MENU_ENUM_LABEL_FAVORITES:
BIND_ACTION_OK(cbs, action_ok_push_content_list);
break;
@ -4098,6 +4261,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS:
BIND_ACTION_OK(cbs, action_ok_netplay_lan_scan_list);
break;
case MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM:
BIND_ACTION_OK(cbs, action_ok_netplay_connect_room);
break;
case MENU_ENUM_LABEL_LAKKA_SERVICES:
BIND_ACTION_OK(cbs, action_ok_lakka_services);
break;

View File

@ -474,6 +474,7 @@ static int menu_cbs_init_bind_right_compare_type(menu_file_list_cbs_t *cbs,
if ( string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_TAB)) ||
@ -594,6 +595,7 @@ static int menu_cbs_init_bind_right_compare_label(menu_file_list_cbs_t *cbs,
if ( string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_TAB)) ||
@ -632,6 +634,7 @@ int menu_cbs_init_bind_right(menu_file_list_cbs_t *cbs,
if ( string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_HISTORY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_PLAYLISTS_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MAIN_MENU)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_MUSIC_TAB)) ||
string_is_equal(menu_label, msg_hash_to_str(MENU_ENUM_LABEL_IMAGES_TAB)) ||

View File

@ -21,6 +21,7 @@
#ifdef HAVE_CHEEVOS
#include "../../cheevos.h"
#endif
#include "../../verbosity.h"
#ifndef BIND_ACTION_SUBLABEL
#define BIND_ACTION_SUBLABEL(cbs, name) \
@ -28,6 +29,11 @@
cbs->action_sublabel_ident = #name;
#endif
#ifdef HAVE_NETWORKING
#include "../../network/netplay/netplay.h"
#include "../../network/netplay/netplay_discovery.h"
#endif
#define default_sublabel_macro(func_name, lbl) \
static int (func_name)(file_list_t *list, unsigned type, unsigned i, const char *label, const char *path, char *s, size_t len) \
{ \
@ -117,6 +123,8 @@ default_sublabel_macro(action_bind_sublabel_content_history_size, MENU_
default_sublabel_macro(action_bind_sublabel_menu_input_unified_controls, MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS)
default_sublabel_macro(action_bind_sublabel_onscreen_notifications_enable, MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE)
/* MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM*/
static int action_bind_sublabel_cheevos_entry(
file_list_t *list,
unsigned type, unsigned i,
@ -136,6 +144,22 @@ static int action_bind_sublabel_cheevos_entry(
return 0;
}
static int action_bind_sublabel_netplay_room(
file_list_t *list,
unsigned type, unsigned i,
const char *label, const char *path,
char *s, size_t len)
{
if (i < 1)
return 0;
snprintf(s,len, "%s (%s)\n%s (%08x)",
netplay_room_list[i - 1].corename, netplay_room_list[i - 1].coreversion,
netplay_room_list[i - 1].gamename, netplay_room_list[i - 1].gamecrc);
//strlcpy(s, netplay_room_list[i - 1].corename, len);
return 0;
}
static int action_bind_sublabel_generic(
file_list_t *list,
unsigned type, unsigned i,
@ -233,6 +257,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_entry);
break;
case MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_room);
break;
case MENU_ENUM_LABEL_CHEEVOS_ENABLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_enable);
break;

View File

@ -257,6 +257,8 @@ static int action_get_title_group_settings(const char *path, const char *label,
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB), len);
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_ADD_TAB)))
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_TAB), len);
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)))
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_TAB), len);
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU)))
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU), len);
else

View File

@ -96,6 +96,9 @@ enum
XMB_TEXTURE_MUSICS,
XMB_TEXTURE_MOVIES,
#endif
#ifdef HAVE_NETWORKING
XMB_TEXTURE_NETPLAY,
#endif
#ifdef HAVE_IMAGEVIEWER
XMB_TEXTURE_IMAGES,
#endif
@ -151,10 +154,15 @@ enum
#ifdef HAVE_IMAGEVIEWER
XMB_SYSTEM_TAB_IMAGES,
#endif
XMB_SYSTEM_TAB_ADD
XMB_SYSTEM_TAB_ADD,
#ifdef HAVE_NETWORKING
XMB_SYSTEM_TAB_NETPLAY
#endif
};
#ifdef HAVE_LIBRETRODB
#ifdef HAVE_NETWORKING
#define XMB_SYSTEM_TAB_END XMB_SYSTEM_TAB_NETPLAY
#elif defined(HAVE_LIBRETRODB)
#define XMB_SYSTEM_TAB_END XMB_SYSTEM_TAB_ADD
#elif defined(HAVE_IMAGEVIEWER)
#define XMB_SYSTEM_TAB_END XMB_SYSTEM_TAB_IMAGES
@ -164,6 +172,7 @@ enum
#define XMB_SYSTEM_TAB_END XMB_SYSTEM_TAB_HISTORY
#endif
typedef struct xmb_handle
{
file_list_t *menu_stack_old;
@ -300,6 +309,7 @@ typedef struct xmb_handle
xmb_node_t settings_tab_node;
xmb_node_t history_tab_node;
xmb_node_t add_tab_node;
xmb_node_t netplay_tab_node;
font_data_t *font;
font_data_t *font2;
@ -1474,6 +1484,8 @@ static xmb_node_t* xmb_get_node(xmb_handle_t *xmb, unsigned i)
return &xmb->history_tab_node;
case XMB_SYSTEM_TAB_ADD:
return &xmb->add_tab_node;
case XMB_SYSTEM_TAB_NETPLAY:
return &xmb->netplay_tab_node;
default:
if (i > xmb->system_tab_end)
return xmb_get_userdata_from_horizontal_list(
@ -3217,6 +3229,9 @@ static void *xmb_init(void **userdata)
if (settings->menu.xmb.show_add)
xmb->tabs[++xmb->system_tab_end] = XMB_SYSTEM_TAB_ADD;
#endif
#ifdef HAVE_NETWORKING
xmb->tabs[++xmb->system_tab_end] = XMB_SYSTEM_TAB_NETPLAY;
#endif
menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL);
@ -3432,6 +3447,8 @@ static const char *xmb_texture_path(unsigned id)
return "off.png";
case XMB_TEXTURE_ADD:
return "add.png";
case XMB_TEXTURE_NETPLAY:
return "wifi.png";
case XMB_TEXTURE_KEY:
return "key.png";
case XMB_TEXTURE_KEY_HOVER:
@ -3482,6 +3499,12 @@ static void xmb_context_reset_textures(
xmb->add_tab_node.icon = xmb->textures.list[XMB_TEXTURE_ADD];
xmb->add_tab_node.alpha = xmb->categories.active.alpha;
xmb->add_tab_node.zoom = xmb->categories.active.zoom;
#ifdef HAVE_NETWORKING
xmb->netplay_tab_node.icon = xmb->textures.list[XMB_TEXTURE_NETPLAY];
xmb->netplay_tab_node.alpha = xmb->categories.active.alpha;
xmb->netplay_tab_node.zoom = xmb->categories.active.zoom;
#endif
}
static void xmb_context_reset_background(const char *iconpath)
@ -3794,6 +3817,12 @@ static void xmb_list_cache(void *data, enum menu_list_type type, unsigned action
menu_stack->list[stack_size - 1].type =
MENU_ADD_TAB;
break;
case XMB_SYSTEM_TAB_NETPLAY:
menu_stack->list[stack_size - 1].label =
strdup(msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB));
menu_stack->list[stack_size - 1].type =
MENU_NETPLAY_TAB;
break;
default:
menu_stack->list[stack_size - 1].label =
strdup(msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU));

View File

@ -244,11 +244,6 @@ static int menu_displaylist_parse_netplay(
MENU_ENUM_LABEL_NETPLAY_DISCONNECT,
MENU_SETTING_ACTION, 0, 0);
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS),
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_SETTINGS),
MENU_ENUM_LABEL_NETWORK_SETTINGS, MENU_SETTING_GROUP, 0, 0);
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS),
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS),
@ -2693,6 +2688,11 @@ static int menu_displaylist_parse_load_content_settings(
MENU_ENUM_LABEL_CORE_INPUT_REMAPPING_OPTIONS,
MENU_SETTING_ACTION, 0, 0);
#ifdef HAVE_NETWORKING
menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_NETPLAY,
PARSE_ACTION, false);
#endif
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS),
@ -2926,6 +2926,7 @@ static int menu_displaylist_parse_add_content_list(
static int menu_displaylist_parse_scan_directory_list(
menu_displaylist_info_t *info)
{
#ifdef HAVE_LIBRETRODB
menu_entries_append_enum(info->list,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY),
@ -2943,6 +2944,37 @@ static int menu_displaylist_parse_scan_directory_list(
return 0;
}
static int menu_displaylist_parse_netplay_room_list(
menu_displaylist_info_t *info)
{
#ifdef HAVE_NETWORKING
menu_entries_append_enum(info->list,
"Refresh Room List",
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS),
MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS,
MENU_SETTING_ACTION, 0, 0);
if (netplay_room_count > 0)
{
unsigned i;
for (i = 0; i < netplay_room_count; i++)
{
char s[PATH_MAX_LENGTH];
snprintf(s, sizeof(s), "Nickname: %s", netplay_room_list[i].nickname);
const char *label = s;
menu_entries_append_enum(info->list,
label,
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM),
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
MENU_WIFI, 0, 0);
}
}
#endif
return 0;
}
static int menu_displaylist_parse_options(
menu_displaylist_info_t *info)
{
@ -3777,6 +3809,12 @@ static bool menu_displaylist_push_internal(
return false;
return true;
}
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)))
{
if (!menu_displaylist_ctl(DISPLAYLIST_NETPLAY_ROOM_LIST, info))
return false;
return true;
}
else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU)))
{
if (!menu_displaylist_ctl(DISPLAYLIST_HORIZONTAL, info))
@ -3905,6 +3943,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
case DISPLAYLIST_ADD_CONTENT_LIST:
case DISPLAYLIST_CONFIGURATIONS_LIST:
case DISPLAYLIST_SCAN_DIRECTORY_LIST:
case DISPLAYLIST_NETPLAY_ROOM_LIST:
case DISPLAYLIST_LOAD_CONTENT_LIST:
case DISPLAYLIST_USER_BINDS_LIST:
case DISPLAYLIST_ACCOUNTS_LIST:
@ -5308,6 +5347,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
case DISPLAYLIST_SCAN_DIRECTORY_LIST:
ret = menu_displaylist_parse_scan_directory_list(info);
info->need_push = true;
info->need_refresh = true;
break;
case DISPLAYLIST_NETPLAY_ROOM_LIST:
ret = menu_displaylist_parse_netplay_room_list(info);
info->need_push = true;
info->need_refresh = true;
break;

View File

@ -151,6 +151,7 @@ enum menu_displaylist_ctl_state
DISPLAYLIST_ADD_CONTENT_LIST,
DISPLAYLIST_CONFIGURATIONS_LIST,
DISPLAYLIST_SCAN_DIRECTORY_LIST,
DISPLAYLIST_NETPLAY_ROOM_LIST,
DISPLAYLIST_ARCHIVE_ACTION,
DISPLAYLIST_ARCHIVE_ACTION_DETECT_CORE,
DISPLAYLIST_CORE_CONTENT,

View File

@ -50,6 +50,7 @@ RETRO_BEGIN_DECLS
#define MENU_SETTINGS_CORE_OPTION_START 0x10000
#define MENU_SETTINGS_PLAYLIST_ASSOCIATION_START 0x20000
#define MENU_SETTINGS_CHEEVOS_START 0x40000
#define MENU_SETTINGS_NETPLAY_ROOMS_START 0x80000
enum menu_image_type
{
@ -154,6 +155,7 @@ enum menu_settings_type
MENU_MUSIC_TAB,
MENU_VIDEO_TAB,
MENU_IMAGES_TAB,
MENU_NETPLAY_TAB,
MENU_ADD_TAB,
MENU_PLAYLISTS_TAB,
MENU_SETTING_NO_ITEM,

View File

@ -746,6 +746,7 @@ enum msg_hash_enums
MENU_LABEL(NETPLAY_LAN_SCAN_SETTINGS),
MENU_ENUM_LABEL_CONNECT_WIFI,
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
MENU_ENUM_LABEL_CONNECT_NETPLAY_LAN,
MENU_LABEL(MENU_ENUM_LINEAR_FILTER),
@ -867,6 +868,7 @@ enum msg_hash_enums
MENU_LABEL(SCAN_THIS_DIRECTORY),
MENU_LABEL(SCAN_DIRECTORY),
MENU_LABEL(SCAN_FILE),
MENU_LABEL(NETPLAY_REFRESH_ROOMS),
MENU_LABEL(ADD_CONTENT_LIST),
MENU_LABEL(CONFIGURATIONS_LIST),
@ -1146,6 +1148,7 @@ enum msg_hash_enums
MENU_LABEL(SETTINGS_TAB),
MENU_LABEL(HISTORY_TAB),
MENU_LABEL(ADD_TAB),
MENU_LABEL(NETPLAY_TAB),
MENU_LABEL(PLAYLISTS_TAB),
MENU_LABEL(MAIN_MENU),
MENU_LABEL(INPUT_SETTINGS),

View File

@ -57,6 +57,8 @@ void audio_sample_net(int16_t left, int16_t right);
size_t audio_sample_batch_net(const int16_t *data, size_t frames);
bool init_netplay_deferred(const char* server, unsigned port);
/**
* init_netplay
* @direct_host : Host to connect to directly, if applicable (client only)

View File

@ -18,6 +18,7 @@
#define __RARCH_NETPLAY_DISCOVERY_H
#include <net/net_compat.h>
#include <retro_miscellaneous.h>
#define NETPLAY_HOST_STR_LEN 32
@ -44,6 +45,24 @@ struct netplay_host_list {
size_t size;
};
/* data is ordered like this on the server, I left it in this ordered
for reference */
struct netplay_room
{
char nickname [PATH_MAX_LENGTH];
char address [PATH_MAX_LENGTH];
int port;
char corename [PATH_MAX_LENGTH];
char coreversion [PATH_MAX_LENGTH];
char gamename [PATH_MAX_LENGTH];
int gamecrc;
int timestamp;
};
struct netplay_room *netplay_room_list;
int netplay_room_count;
/** Initialize Netplay discovery */
bool init_netplay_discovery(void);

View File

@ -21,6 +21,7 @@
#include <boolean.h>
#include <compat/strl.h>
#include <retro_assert.h>
#include <string/stdstring.h>
#include "netplay_private.h"
@ -28,6 +29,11 @@
#include "../../input/input_driver.h"
#include "../../runloop.h"
#include "../../tasks/tasks_internal.h"
#include <file/file_path.h>
#include "../../file_path_special.h"
#include "paths.h"
/* Only used before init_netplay */
static bool netplay_enabled = false;
static bool netplay_is_client = false;
@ -38,6 +44,11 @@ static netplay_t *netplay_data = NULL;
/* Used to avoid recursive netplay calls */
static bool in_netplay = false;
/* Used for deferred netplay initialization */
static bool netplay_client_deferred = false;
static char server_address_deferred[512] = "";
static unsigned server_port_deferred = 0;
/**
* netplay_is_alive:
* @netplay : pointer to netplay object
@ -151,6 +162,20 @@ static bool get_self_input_state(netplay_t *netplay)
return true;
}
bool init_netplay_deferred(const char* server, unsigned port)
{
if (!string_is_empty(server) && port != 0)
{
strlcpy(server_address_deferred, server, sizeof(server_address_deferred));
server_port_deferred = port;
netplay_client_deferred = true;
}
else
netplay_client_deferred = false;
return netplay_client_deferred;
}
/**
* netplay_poll:
* @netplay : pointer to netplay object
@ -390,6 +415,36 @@ static int16_t netplay_input_state(netplay_t *netplay,
}
}
static int reannounce = 0;
static void netplay_announce_cb(void *task_data, void *user_data, const char *error)
{
RARCH_LOG("Announcing netplay game... \n");
return;
}
static void netplay_announce()
{
rarch_system_info_t *system = NULL;
settings_t *settings = config_get_ptr();
uint32_t *content_crc_ptr = NULL;
content_get_crc(&content_crc_ptr);
runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system);
char url [2048] = "http://lobby.libretro.com/raw/?";
char buf [2048];
buf[0] = '\0';
snprintf(buf, sizeof(buf), "%susername=%s&corename=%s&coreversion=%s&"
"gamename=%s&gamecrc=%d&port=%d",
url, settings->username, system->info.library_name,
system->info.library_version,
path_basename(path_get(RARCH_PATH_BASENAME)),*content_crc_ptr,
settings->netplay.port);
task_push_http_transfer(buf, true, NULL, netplay_announce_cb, NULL);
}
int16_t input_state_net(unsigned port, unsigned device,
unsigned idx, unsigned id)
{
@ -519,7 +574,9 @@ static void netplay_frontend_paused(netplay_t *netplay, bool paused)
bool netplay_pre_frame(netplay_t *netplay)
{
bool sync_stalled;
reannounce ++;
if (netplay->is_server && (reannounce % 3600 == 0))
netplay_announce();
retro_assert(netplay);
/* FIXME: This is an ugly way to learn we're not paused anymore */
@ -883,12 +940,14 @@ bool init_netplay(void *direct_host, const char *server, unsigned port)
runloop_msg_queue_push(
msg_hash_to_str(MSG_WAITING_FOR_CLIENT),
0, 180, false);
netplay_announce();
}
netplay_data = (netplay_t*)netplay_new(
netplay_is_client ? direct_host : NULL,
netplay_is_client ? server : NULL,
port ? port : RARCH_DEFAULT_PORT,
netplay_is_client ? (!netplay_client_deferred ? server : server_address_deferred) : NULL,
port ? ( !netplay_client_deferred ? port : server_port_deferred) : RARCH_DEFAULT_PORT,
settings->netplay.stateless_mode, settings->netplay.check_frames, &cbs,
settings->netplay.nat_traversal, settings->username,
quirks);
@ -904,6 +963,8 @@ bool init_netplay(void *direct_host, const char *server, unsigned port)
return false;
}
/**
* netplay_driver_ctl
*

184
tasks/task_netplay_crc.c Normal file
View File

@ -0,0 +1,184 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2016 - Jean-André Santoni
*
* 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/>.
*/
#include <string.h>
#include <errno.h>
#include <file/nbio.h>
#include <formats/image.h>
#include <compat/strl.h>
#include <retro_assert.h>
#include <retro_miscellaneous.h>
#include <lists/string_list.h>
#include <rhash.h>
#include <string/stdstring.h>
#include <file/file_path.h>
#include <lists/dir_list.h>
#include "tasks_internal.h"
#include "../file_path_special.h"
#include "../verbosity.h"
#include "../configuration.h"
#include "../playlist.h"
#include "../command.h"
#include "../core_info.h"
typedef struct
{
struct string_list *lpl_list;
char crc[PATH_MAX_LENGTH];
char path[PATH_MAX_LENGTH];
char hostname[512];
char corename[PATH_MAX_LENGTH];
bool found;
} netplay_crc_handle_t;
static void netplay_crc_scan_callback(void *task_data,
void *user_data, const char *error)
{
netplay_crc_handle_t *state = (netplay_crc_handle_t*)task_data;
core_info_list_t *info = NULL;
content_ctx_info_t content_info = {0};
int i;
core_info_get_list(&info);
if (!state)
return;
for (i=0; i < info->count; i++)
{
if(string_is_equal(info->list[i].core_name, state->corename))
break;
}
printf("Hostname: %s\n", state->hostname);
printf("Content: %s\n", state->path);
printf("Corename: %s\n", state->corename);
printf("Corepath: %s\n", info->list[i].path);
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED, state->hostname);
task_push_content_load_default(
info->list[i].path, state->path,
&content_info,
CORE_TYPE_PLAIN,
CONTENT_MODE_LOAD_CONTENT_WITH_NEW_CORE_FROM_MENU,
NULL, NULL);
free(state);
}
static void task_netplay_crc_scan_handler(retro_task_t *task)
{
netplay_crc_handle_t *state = (netplay_crc_handle_t*)task->state;
size_t i, j;
task_set_progress(task, 0);
task_set_title(task, strdup("Checking for ROM presence."));
task_set_finished(task, false);
if (!state->lpl_list)
{
task_set_progress(task, 100);
task_set_title(task, strdup("Playlist directory not found."));
task_set_finished(task, true);
free(state);
return;
}
if (state->lpl_list->size == 0)
goto no_playlists;
for (i = 0; i < state->lpl_list->size; i++)
{
const char *lpl_path = state->lpl_list->elems[i].data;
if (!strstr(lpl_path, file_path_str(FILE_PATH_LPL_EXTENSION)))
continue;
printf("%s\n", lpl_path);
playlist_t *playlist = playlist_init(lpl_path, 99999);
for (j = 0; j < playlist->size; j++)
{
printf("%s\n", playlist->entries[j].crc32);
if (string_is_equal(playlist->entries[j].crc32, state->crc))
{
strlcpy(state->path, playlist->entries[j].path, sizeof(state->path));
state->found = true;
task_set_data(task, state);
task_set_progress(task, 100);
task_set_title(task, strdup("Game found."));
task_set_finished(task, true);
string_list_free(state->lpl_list);
return;
}
task_set_progress(task, (int)(j/playlist->size*100.0));
}
}
no_playlists:
string_list_free(state->lpl_list);
task_set_progress(task, 100);
task_set_title(task, strdup("No game found."));
task_set_finished(task, true);
return;
}
bool task_push_netplay_crc_scan(uint32_t crc,
const char *hostname, const char *corename)
{
settings_t *settings = config_get_ptr();
retro_task_t *task = (retro_task_t *)calloc(1, sizeof(*task));
netplay_crc_handle_t *state = (netplay_crc_handle_t*)calloc(1, sizeof(*state));
if (!task || !state)
goto error;
state->crc[0] = '\0';
snprintf(state->crc, sizeof(state->crc), "%08X|crc", crc);
state->hostname[0] = '\0';
snprintf(state->hostname, sizeof(state->hostname), "%s", hostname);
state->corename[0] = '\0';
snprintf(state->corename, sizeof(state->corename), "%s", corename);
state->lpl_list = dir_list_new(settings->directory.playlist,
NULL, true, true, true, false);
state->found = false;
/* blocking means no other task can run while this one is running,
* which is the default */
task->type = TASK_TYPE_BLOCKING;
task->state = state;
task->handler = task_netplay_crc_scan_handler;
task->callback = netplay_crc_scan_callback;
task->title = strdup("Checking for ROM presence.");
task_queue_ctl(TASK_QUEUE_CTL_PUSH, task);
return true;
error:
if (state)
free(state);
if (task)
free(task);
return false;
}

View File

@ -98,6 +98,9 @@ bool task_push_wifi_scan(void);
bool task_push_netplay_lan_scan(void);
bool task_push_netplay_crc_scan(uint32_t crc,
const char *hostname, const char *corename);
#endif
bool task_push_image_load(const char *fullpath,