mirror of
https://github.com/libretro/RetroArch
synced 2025-03-17 10:21:26 +00:00
Merge pull request #14054 from Cthulhu-throwaway/netplay-refactor
(Netplay) Some refactoring and fixes
This commit is contained in:
commit
838e5117d0
@ -5959,113 +5959,109 @@ static int action_ok_wifi_disconnect(const char *path,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int action_ok_netplay_connect_room(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
static int action_ok_netplay_connect_room(const char *path, const char *label,
|
||||
unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
char tmp_hostname[4115];
|
||||
char hostname[512];
|
||||
struct netplay_room *room;
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
|
||||
|
||||
if (room_index >= (unsigned)net_st->room_count)
|
||||
return menu_cbs_exit();
|
||||
|
||||
tmp_hostname[0] = '\0';
|
||||
room = &net_st->room_list[room_index];
|
||||
|
||||
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);
|
||||
|
||||
if (net_st->room_list[room_index].host_method == NETPLAY_HOST_METHOD_MITM)
|
||||
snprintf(tmp_hostname,
|
||||
sizeof(tmp_hostname),
|
||||
"%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_session);
|
||||
if (room->host_method == NETPLAY_HOST_METHOD_MITM)
|
||||
snprintf(hostname, sizeof(hostname), "%s|%d|%s",
|
||||
room->mitm_address, room->mitm_port, room->mitm_session);
|
||||
else
|
||||
snprintf(tmp_hostname,
|
||||
sizeof(tmp_hostname),
|
||||
"%s|%d",
|
||||
net_st->room_list[room_index].address,
|
||||
net_st->room_list[room_index].port);
|
||||
snprintf(hostname, sizeof(hostname), "%s|%d", room->address, room->port);
|
||||
|
||||
#if 0
|
||||
RARCH_LOG("[lobby] connecting to: %s with game: %s/%08x\n",
|
||||
tmp_hostname,
|
||||
net_st->room_list[room_index].gamename,
|
||||
net_st->room_list[room_index].gamecrc);
|
||||
RARCH_LOG("[Lobby] Connecting to: %s with game: %s/%08x\n",
|
||||
hostname, room->gamename, room->gamecrc);
|
||||
#endif
|
||||
|
||||
task_push_netplay_crc_scan(
|
||||
net_st->room_list[room_index].gamecrc,
|
||||
net_st->room_list[room_index].gamename,
|
||||
tmp_hostname,
|
||||
net_st->room_list[room_index].corename,
|
||||
net_st->room_list[room_index].subsystem_name);
|
||||
task_push_netplay_crc_scan(room->gamecrc, room->gamename, hostname,
|
||||
room->corename, room->subsystem_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void netplay_refresh_rooms_cb(retro_task_t *task,
|
||||
void *task_data, void *user_data, const char *error)
|
||||
static void netplay_refresh_rooms_cb(retro_task_t *task, void *task_data,
|
||||
void *user_data, const char *error)
|
||||
{
|
||||
char *new_data = NULL;
|
||||
char *room_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;
|
||||
bool refresh = false;
|
||||
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
|
||||
free(net_st->room_list);
|
||||
net_st->room_list = NULL;
|
||||
net_st->room_count = 0;
|
||||
|
||||
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 (error)
|
||||
{
|
||||
RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED),
|
||||
error);
|
||||
return;
|
||||
RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), error);
|
||||
goto done;
|
||||
}
|
||||
if (!data || !data->data || !data->len || data->status != 200)
|
||||
{
|
||||
RARCH_ERR("%s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED));
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
|
||||
new_data = (char*)realloc(data->data, data->len + 1);
|
||||
if (!new_data)
|
||||
return;
|
||||
data->data = new_data;
|
||||
data->data[data->len] = '\0';
|
||||
room_data = (char*)malloc(data->len + 1);
|
||||
if (!room_data)
|
||||
goto done;
|
||||
memcpy(room_data, data->data, data->len);
|
||||
room_data[data->len] = '\0';
|
||||
|
||||
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(room_data))
|
||||
{
|
||||
int i;
|
||||
int room_count;
|
||||
|
||||
netplay_rooms_parse(data->data);
|
||||
netplay_rooms_parse(room_data);
|
||||
|
||||
net_st->room_count = netplay_rooms_get_count();
|
||||
net_st->room_list = (struct netplay_room*)calloc(net_st->room_count,
|
||||
sizeof(*net_st->room_list));
|
||||
|
||||
for (i = 0; i < net_st->room_count; i++)
|
||||
memcpy(&net_st->room_list[i], netplay_room_get(i),
|
||||
room_count = netplay_rooms_get_count();
|
||||
if (room_count > 0)
|
||||
{
|
||||
net_st->room_list = (struct netplay_room*)calloc(room_count,
|
||||
sizeof(*net_st->room_list));
|
||||
if (net_st->room_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
net_st->room_count = room_count;
|
||||
for (i = 0; i < room_count; i++)
|
||||
memcpy(&net_st->room_list[i], netplay_room_get(i),
|
||||
sizeof(*net_st->room_list));
|
||||
}
|
||||
}
|
||||
|
||||
netplay_rooms_free();
|
||||
}
|
||||
|
||||
free(room_data);
|
||||
|
||||
done:
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
|
||||
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
|
||||
}
|
||||
@ -6073,92 +6069,81 @@ static void netplay_refresh_rooms_cb(retro_task_t *task,
|
||||
static int action_ok_push_netplay_refresh_rooms(const char *path,
|
||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||
{
|
||||
#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);
|
||||
task_push_http_transfer(FILE_PATH_LOBBY_LIBRETRO_URL "list", 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)
|
||||
static void netplay_refresh_lan_cb(retro_task_t *task, void *task_data,
|
||||
void *user_data, const char *error)
|
||||
{
|
||||
int i;
|
||||
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;
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
|
||||
free(net_st->room_list);
|
||||
net_st->room_list = NULL;
|
||||
net_st->room_count = 0;
|
||||
|
||||
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 (!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 deinit;
|
||||
|
||||
if (!netplay_discovery_driver_ctl(
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts) ||
|
||||
!hosts)
|
||||
goto finished;
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts))
|
||||
goto done;
|
||||
if (!hosts || !hosts->size)
|
||||
goto done;
|
||||
|
||||
if (net_st->room_list)
|
||||
free(net_st->room_list);
|
||||
net_st->room_list =
|
||||
(struct netplay_room*)calloc(hosts->size, sizeof(*net_st->room_list));
|
||||
if (!net_st->room_list)
|
||||
goto done;
|
||||
net_st->room_count = hosts->size;
|
||||
|
||||
net_st->room_list = NULL;
|
||||
net_st->room_count = 0;
|
||||
|
||||
if (hosts->size)
|
||||
for (i = 0; i < net_st->room_count; i++)
|
||||
{
|
||||
int i;
|
||||
struct netplay_host *host = &hosts->hosts[i];
|
||||
struct netplay_room *room = &net_st->room_list[i];
|
||||
|
||||
net_st->room_count = hosts->size;
|
||||
net_st->room_list = (struct netplay_room*)calloc(net_st->room_count,
|
||||
sizeof(*net_st->room_list));
|
||||
room->gamecrc = host->content_crc;
|
||||
room->port = host->port;
|
||||
|
||||
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];
|
||||
strlcpy(room->nickname, host->nick, sizeof(room->nickname));
|
||||
strlcpy(room->frontend, host->frontend, sizeof(room->frontend));
|
||||
strlcpy(room->corename, host->core, sizeof(room->corename));
|
||||
strlcpy(room->coreversion, host->core_version,
|
||||
sizeof(room->coreversion));
|
||||
strlcpy(room->retroarch_version, host->retroarch_version,
|
||||
sizeof(room->retroarch_version));
|
||||
strlcpy(room->gamename, host->content, sizeof(room->gamename));
|
||||
strlcpy(room->subsystem_name, host->subsystem_name,
|
||||
sizeof(room->subsystem_name));
|
||||
strlcpy(room->address, host->address, sizeof(room->address));
|
||||
|
||||
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->connectable = true;
|
||||
room->is_retroarch = true;
|
||||
room->lan = true;
|
||||
}
|
||||
room->has_password = host->has_password;
|
||||
room->has_spectate_password = host->has_spectate_password;
|
||||
|
||||
room->connectable = true;
|
||||
room->is_retroarch = true;
|
||||
room->lan = true;
|
||||
}
|
||||
|
||||
done:
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
|
||||
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
|
||||
|
||||
finished:
|
||||
deinit:
|
||||
deinit_netplay_discovery();
|
||||
}
|
||||
|
||||
|
@ -1494,93 +1494,48 @@ static int action_bind_sublabel_cheat_desc(
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
static int action_bind_sublabel_netplay_room(
|
||||
file_list_t *list,
|
||||
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)
|
||||
{
|
||||
uint32_t gamecrc = 0;
|
||||
const char *ra_version = NULL;
|
||||
const char *corename = NULL;
|
||||
const char *gamename = NULL;
|
||||
const char *core_ver = NULL;
|
||||
const char *frontend = NULL;
|
||||
const char *na = NULL;
|
||||
const char *subsystem = NULL;
|
||||
char buf[512];
|
||||
struct netplay_room *room;
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
|
||||
|
||||
if (room_index >= (unsigned)net_st->room_count)
|
||||
return menu_cbs_exit();
|
||||
|
||||
ra_version = net_st->room_list[room_index].retroarch_version;
|
||||
corename = net_st->room_list[room_index].corename;
|
||||
gamename = net_st->room_list[room_index].gamename;
|
||||
core_ver = net_st->room_list[room_index].coreversion;
|
||||
gamecrc = net_st->room_list[room_index].gamecrc;
|
||||
frontend = net_st->room_list[room_index].frontend;
|
||||
subsystem = net_st->room_list[room_index].subsystem_name;
|
||||
na = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE);
|
||||
room = &net_st->room_list[room_index];
|
||||
|
||||
if (string_is_empty(subsystem) || string_is_equal(subsystem,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)))
|
||||
{
|
||||
snprintf(s, len,
|
||||
"%s: %s (%s)\n%s: %s (%s)\nGame: %s (%08lx)",
|
||||
msg_hash_to_str(MSG_PROGRAM),
|
||||
string_is_empty(ra_version) ? na : ra_version,
|
||||
string_is_empty(frontend) ? na : frontend,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
||||
corename, core_ver,
|
||||
!string_is_equal(gamename, na) ? gamename : na,
|
||||
(unsigned long)gamecrc);
|
||||
}
|
||||
snprintf(s, len,
|
||||
"%s: %s (%s)\n"
|
||||
"%s: %s (%s)\n"
|
||||
"%s: %s ",
|
||||
msg_hash_to_str(MSG_PROGRAM),
|
||||
!string_is_empty(room->retroarch_version) ? room->retroarch_version :
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
||||
(!string_is_empty(room->frontend) &&
|
||||
!string_is_equal_case_insensitive(room->frontend, "N/A")) ?
|
||||
room->frontend :
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
||||
room->corename, room->coreversion,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT),
|
||||
(!string_is_empty(room->gamename) &&
|
||||
!string_is_equal_case_insensitive(room->gamename, "N/A")) ?
|
||||
room->gamename :
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE));
|
||||
|
||||
if (string_is_empty(room->subsystem_name) ||
|
||||
string_is_equal_case_insensitive(room->subsystem_name, "N/A"))
|
||||
snprintf(buf, sizeof(buf), "(%08lX)", (unsigned long)room->gamecrc);
|
||||
else
|
||||
{
|
||||
if (strstr(gamename, "|"))
|
||||
{
|
||||
char buf[4096];
|
||||
unsigned i = 0;
|
||||
struct string_list list = {0};
|
||||
snprintf(buf, sizeof(buf), "(%s)", room->subsystem_name);
|
||||
|
||||
string_list_initialize(&list);
|
||||
string_split_noalloc(&list, gamename, "|");
|
||||
strlcat(s, buf, len);
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
for (i = 0; i < list.size; i++)
|
||||
{
|
||||
strlcat(buf, " ", sizeof(buf));
|
||||
strlcat(buf, list.elems[i].data, sizeof(buf));
|
||||
/* Never terminate a UI string with a newline */
|
||||
if (i != list.size - 1)
|
||||
strlcat(buf, "\n", sizeof(buf));
|
||||
}
|
||||
snprintf(s, len,
|
||||
"%s: %s (%s)\n%s: %s (%s)\nSubsystem: %s\nGames:\n%s",
|
||||
msg_hash_to_str(MSG_PROGRAM),
|
||||
string_is_empty(ra_version) ? na : ra_version,
|
||||
string_is_empty(frontend) ? na : frontend,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
||||
corename, core_ver, subsystem,
|
||||
!string_is_equal(gamename, na) ? buf : na
|
||||
);
|
||||
string_list_deinitialize(&list);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(s, len,
|
||||
"%s: %s (%s)\n%s: %s (%s)\nSubsystem: %s\nGame: %s (%08lx)",
|
||||
msg_hash_to_str(MSG_PROGRAM),
|
||||
string_is_empty(ra_version) ? na : ra_version,
|
||||
string_is_empty(frontend) ? na : frontend,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
||||
corename, core_ver, subsystem,
|
||||
!string_is_equal(gamename, na) ? gamename : na,
|
||||
(unsigned long)gamecrc);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1590,10 +1545,10 @@ static int action_bind_sublabel_netplay_kick_client(file_list_t *list,
|
||||
char *s, size_t len)
|
||||
{
|
||||
char buf[256];
|
||||
netplay_client_info_t *client = NULL;
|
||||
const char *status = NULL;
|
||||
size_t idx = list->list[i].entry_idx;
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
netplay_client_info_t *client;
|
||||
const char *status = NULL;
|
||||
size_t idx = list->list[i].entry_idx;
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
|
||||
if (idx >= net_st->client_info_count)
|
||||
return menu_cbs_exit();
|
||||
@ -1625,20 +1580,17 @@ static int action_bind_sublabel_netplay_kick_client(file_list_t *list,
|
||||
snprintf(buf, sizeof(buf), "%s: %s",
|
||||
msg_hash_to_str(MSG_NETPLAY_CHAT_SUPPORTED),
|
||||
msg_hash_to_str((client->protocol >= 6) ?
|
||||
MENU_ENUM_LABEL_VALUE_YES :
|
||||
MENU_ENUM_LABEL_VALUE_NO));
|
||||
MENU_ENUM_LABEL_VALUE_YES : MENU_ENUM_LABEL_VALUE_NO));
|
||||
strlcat(s, buf, len);
|
||||
|
||||
if (client->ping >= 0)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "\nPing: %u",
|
||||
(unsigned)client->ping);
|
||||
snprintf(buf, sizeof(buf), "\nPing: %u", (unsigned)client->ping);
|
||||
strlcat(s, buf, len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int action_bind_sublabel_playlist_entry(
|
||||
|
@ -10386,9 +10386,16 @@ static unsigned menu_displaylist_build_shader_parameter(
|
||||
unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||
{
|
||||
int i;
|
||||
char buf[256];
|
||||
char passworded[64];
|
||||
char country[8];
|
||||
const char *room_type;
|
||||
struct netplay_room *room;
|
||||
unsigned count = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
bool show_only_connectable = settings->bools.netplay_show_only_connectable;
|
||||
bool show_passworded = settings->bools.netplay_show_passworded;
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, list);
|
||||
|
||||
@ -10400,8 +10407,8 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||
count++;
|
||||
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL) &&
|
||||
!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SERVER, NULL) &&
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_CONNECTED, NULL))
|
||||
!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SERVER, NULL) &&
|
||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_CONNECTED, NULL))
|
||||
{
|
||||
if (menu_entries_append_enum(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT),
|
||||
@ -10412,10 +10419,10 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||
}
|
||||
|
||||
if (menu_entries_append_enum(list,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT),
|
||||
MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT,
|
||||
MENU_SETTING_ACTION, 0, 0))
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT),
|
||||
MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT,
|
||||
MENU_SETTING_ACTION, 0, 0))
|
||||
count++;
|
||||
|
||||
if (menu_entries_append_enum(list,
|
||||
@ -10450,11 +10457,7 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||
|
||||
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];
|
||||
room = &net_st->room_list[i];
|
||||
|
||||
/* Get rid of any room that is not running RetroArch. */
|
||||
if (!room->is_retroarch)
|
||||
@ -10464,7 +10467,7 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||
if the user opt-in. */
|
||||
if (!room->connectable)
|
||||
{
|
||||
if (settings->bools.netplay_show_only_connectable)
|
||||
if (show_only_connectable)
|
||||
continue;
|
||||
|
||||
room_type = msg_hash_to_str(MSG_INTERNET_NOT_CONNECTABLE);
|
||||
@ -10480,7 +10483,7 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||
if the user opt-in. */
|
||||
if (room->has_password || room->has_spectate_password)
|
||||
{
|
||||
if (!settings->bools.netplay_show_passworded)
|
||||
if (!show_passworded)
|
||||
continue;
|
||||
|
||||
snprintf(passworded, sizeof(passworded), "[%s] ",
|
||||
@ -10490,46 +10493,20 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||
*passworded = '\0';
|
||||
|
||||
if (!room->lan && !string_is_empty(room->country))
|
||||
snprintf(country, sizeof(country), " (%s)",
|
||||
room->country);
|
||||
snprintf(country, sizeof(country), " (%s)", room->country);
|
||||
else
|
||||
*country = '\0';
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%s: %s%s",
|
||||
passworded, room_type,
|
||||
room->nickname, country);
|
||||
passworded, room_type, room->nickname, country);
|
||||
|
||||
if (menu_entries_append_enum(list,
|
||||
buf,
|
||||
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))
|
||||
(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;
|
||||
}
|
||||
|
||||
@ -10637,13 +10614,14 @@ static unsigned menu_displaylist_netplay_kick(file_list_t *list)
|
||||
|
||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_REFRESH_CLIENT_INFO, NULL))
|
||||
{
|
||||
char client_id[4];
|
||||
size_t i;
|
||||
char client_id[4];
|
||||
netplay_client_info_t *client;
|
||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||
|
||||
for (i = 0; i < net_st->client_info_count; i++)
|
||||
{
|
||||
netplay_client_info_t *client = &net_st->client_info[i];
|
||||
client = &net_st->client_info[i];
|
||||
|
||||
snprintf(client_id, sizeof(client_id), "%d", client->id);
|
||||
if (menu_entries_append_enum(list, client->name, client_id,
|
||||
@ -10664,7 +10642,6 @@ static unsigned menu_displaylist_netplay_kick(file_list_t *list)
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool menu_displaylist_has_subsystems(void)
|
||||
|
@ -53,7 +53,7 @@ extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
static discord_state_t discord_state_st; /* int64_t alignment */
|
||||
static discord_state_t discord_state_st = {0}; /* int64_t alignment */
|
||||
|
||||
discord_state_t *discord_state_get_ptr(void)
|
||||
{
|
||||
@ -153,99 +153,113 @@ static void handle_discord_error(int errcode, const char* message)
|
||||
{
|
||||
}
|
||||
|
||||
static void handle_discord_join_cb(retro_task_t *task,
|
||||
void *task_data, void *user_data, const char *err)
|
||||
static void handle_discord_join_cb(retro_task_t *task, void *task_data,
|
||||
void *user_data, const char *error)
|
||||
{
|
||||
char join_hostname[PATH_MAX_LENGTH];
|
||||
struct netplay_room *room = NULL;
|
||||
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
||||
discord_state_t *discord_st = &discord_state_st;
|
||||
char hostname[512];
|
||||
struct netplay_room *room;
|
||||
char *room_data = NULL;
|
||||
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
||||
discord_state_t *discord_st = &discord_state_st;
|
||||
|
||||
if (!data || err || !data->data || !data->len)
|
||||
goto finish;
|
||||
if (error)
|
||||
goto done;
|
||||
if (!data || !data->data || !data->len)
|
||||
goto done;
|
||||
if (data->status != 200)
|
||||
goto done;
|
||||
|
||||
data->data = (char*)realloc(data->data, data->len + 1);
|
||||
data->data[data->len] = '\0';
|
||||
room_data = (char*)malloc(data->len + 1);
|
||||
if (!room_data)
|
||||
goto done;
|
||||
memcpy(room_data, data->data, data->len);
|
||||
room_data[data->len] = '\0';
|
||||
|
||||
netplay_rooms_parse(data->data);
|
||||
room = netplay_room_get(0);
|
||||
netplay_rooms_parse(room_data);
|
||||
free(room_data);
|
||||
|
||||
room = netplay_room_get(0);
|
||||
if (room)
|
||||
{
|
||||
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);
|
||||
|
||||
task_push_netplay_crc_scan(room->gamecrc,
|
||||
room->gamename, join_hostname, room->corename, room->subsystem_name);
|
||||
if (room->host_method == NETPLAY_HOST_METHOD_MITM)
|
||||
snprintf(hostname, sizeof(hostname), "%s|%d|%s",
|
||||
room->mitm_address, room->mitm_port, room->mitm_session);
|
||||
else
|
||||
snprintf(hostname, sizeof(hostname), "%s|%d",
|
||||
room->address, room->port);
|
||||
|
||||
task_push_netplay_crc_scan(room->gamecrc, room->gamename, hostname,
|
||||
room->corename, room->subsystem_name);
|
||||
|
||||
discord_st->connecting = true;
|
||||
if (discord_st->ready)
|
||||
discord_update(PRESENCE_NETPLAY_CLIENT);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (user_data)
|
||||
free(user_data);
|
||||
netplay_rooms_free();
|
||||
|
||||
done:
|
||||
free(user_data);
|
||||
}
|
||||
|
||||
static void handle_discord_join(const char* secret)
|
||||
static void handle_discord_join(const char *secret)
|
||||
{
|
||||
char url[2048];
|
||||
struct string_list *list = string_split(secret, "|");
|
||||
char url[512];
|
||||
discord_state_t *discord_st = &discord_state_st;
|
||||
int room_id = (int)strtol(secret, NULL, 10);
|
||||
|
||||
strlcpy(discord_st->peer_party_id,
|
||||
list->elems[0].data, sizeof(discord_st->peer_party_id));
|
||||
snprintf(url, sizeof(url), FILE_PATH_LOBBY_LIBRETRO_URL "%s/",
|
||||
discord_st->peer_party_id);
|
||||
if (room_id)
|
||||
{
|
||||
snprintf(discord_st->peer_party_id, sizeof(discord_st->peer_party_id),
|
||||
"%d", room_id);
|
||||
|
||||
task_push_http_transfer(url, true, NULL, handle_discord_join_cb, NULL);
|
||||
strlcpy(url, FILE_PATH_LOBBY_LIBRETRO_URL, sizeof(url));
|
||||
strlcat(url, discord_st->peer_party_id, sizeof(url));
|
||||
|
||||
task_push_http_transfer(url, true, NULL, handle_discord_join_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_discord_spectate(const char* secret)
|
||||
static void handle_discord_spectate(const char *secret)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
#if 0
|
||||
#ifdef HAVE_MENU
|
||||
static void handle_discord_join_response(void *ignore, const char *line)
|
||||
{
|
||||
/* TODO/FIXME: needs in-game widgets */
|
||||
if (strstr(line, "yes"))
|
||||
Discord_Respond(user_id, DISCORD_REPLY_YES);
|
||||
|
||||
#ifdef HAVE_MENU
|
||||
menu_input_dialog_end();
|
||||
retroarch_menu_running_finished(false);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void handle_discord_join_request(const DiscordUser* request)
|
||||
static void handle_discord_join_request(const DiscordUser *request)
|
||||
{
|
||||
#ifdef HAVE_MENU
|
||||
#if 0
|
||||
char buf[PATH_MAX_LENGTH];
|
||||
menu_input_ctx_line_t line;
|
||||
menu_input_ctx_line_t line = {0};
|
||||
#endif
|
||||
discord_state_t *discord_st = &discord_state_st;
|
||||
|
||||
discord_download_avatar(discord_st, request->userId, request->avatar);
|
||||
|
||||
#if 0
|
||||
/* TODO/FIXME: Needs in-game widgets */
|
||||
retroarch_menu_running();
|
||||
|
||||
memset(&line, 0, sizeof(line));
|
||||
snprintf(buf, sizeof(buf), "%s %s?",
|
||||
msg_hash_to_str(MSG_DISCORD_CONNECTION_REQUEST), request->username);
|
||||
msg_hash_to_str(MSG_DISCORD_CONNECTION_REQUEST), request->username);
|
||||
line.label = buf;
|
||||
line.label_setting = "no_setting";
|
||||
line.cb = handle_discord_join_response;
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../../config.h"
|
||||
@ -32,16 +30,14 @@
|
||||
|
||||
#include <net/net_compat.h>
|
||||
|
||||
#include "../../retroarch_types.h"
|
||||
|
||||
#include "../natt.h"
|
||||
|
||||
#include "netplay_protocol.h"
|
||||
|
||||
#define NETPLAY_NICK_LEN 32
|
||||
#define NETPLAY_HOST_STR_LEN 32
|
||||
#define NETPLAY_HOST_LONGSTR_LEN 256
|
||||
|
||||
#define NETPLAY_MITM_SERVERS 5
|
||||
|
||||
#define NETPLAY_CHAT_MAX_MESSAGES 5
|
||||
#define NETPLAY_CHAT_MAX_SIZE 96
|
||||
#define NETPLAY_CHAT_FRAME_TIME 900
|
||||
@ -132,10 +128,10 @@ enum netplay_host_method
|
||||
|
||||
enum rarch_netplay_discovery_ctl_state
|
||||
{
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_NONE = 0,
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY,
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES,
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_CLEAR_RESPONSES
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_NONE = 0,
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY,
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES,
|
||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_CLEAR_RESPONSES
|
||||
};
|
||||
|
||||
typedef struct netplay netplay_t;
|
||||
@ -143,62 +139,38 @@ typedef struct netplay netplay_t;
|
||||
typedef struct netplay_client_info
|
||||
{
|
||||
uint32_t protocol;
|
||||
int32_t ping;
|
||||
int id;
|
||||
enum rarch_netplay_connection_mode mode;
|
||||
char name[NETPLAY_NICK_LEN];
|
||||
int32_t ping;
|
||||
int id;
|
||||
enum rarch_netplay_connection_mode mode;
|
||||
char name[NETPLAY_NICK_LEN];
|
||||
} netplay_client_info_t;
|
||||
|
||||
struct ad_packet
|
||||
{
|
||||
uint32_t header;
|
||||
int32_t content_crc;
|
||||
int32_t 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
|
||||
{
|
||||
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" },
|
||||
{ "saopaulo", "Sao Paulo, Brazil" },
|
||||
{ "singapore", "Singapore" },
|
||||
{ "custom", "Custom" },
|
||||
};
|
||||
|
||||
struct netplay_room
|
||||
{
|
||||
struct netplay_room *next;
|
||||
int id;
|
||||
int gamecrc;
|
||||
int port;
|
||||
int mitm_port;
|
||||
int gamecrc;
|
||||
int timestamp;
|
||||
int host_method;
|
||||
char country [3];
|
||||
char retroarch_version [33];
|
||||
char nickname [33];
|
||||
char subsystem_name [256];
|
||||
char corename [256];
|
||||
char frontend [256];
|
||||
char coreversion [256];
|
||||
char gamename [256];
|
||||
char address [256];
|
||||
char mitm_handle [33];
|
||||
char mitm_address [256];
|
||||
char mitm_session [33];
|
||||
char nickname[NETPLAY_NICK_LEN];
|
||||
char frontend[NETPLAY_HOST_STR_LEN];
|
||||
char corename[NETPLAY_HOST_STR_LEN];
|
||||
char coreversion[NETPLAY_HOST_STR_LEN];
|
||||
char retroarch_version[NETPLAY_HOST_STR_LEN];
|
||||
char gamename[NETPLAY_HOST_LONGSTR_LEN];
|
||||
char subsystem_name[NETPLAY_HOST_LONGSTR_LEN];
|
||||
char country[3];
|
||||
char address[NETPLAY_HOST_LONGSTR_LEN];
|
||||
char mitm_handle[NETPLAY_HOST_STR_LEN];
|
||||
char mitm_address[NETPLAY_HOST_LONGSTR_LEN];
|
||||
char mitm_session[NETPLAY_HOST_STR_LEN];
|
||||
bool has_password;
|
||||
bool has_spectate_password;
|
||||
bool connectable;
|
||||
@ -216,7 +188,7 @@ struct netplay_host
|
||||
{
|
||||
int content_crc;
|
||||
int port;
|
||||
char address[NETPLAY_HOST_STR_LEN];
|
||||
char address[16];
|
||||
char nick[NETPLAY_NICK_LEN];
|
||||
char frontend[NETPLAY_HOST_STR_LEN];
|
||||
char core[NETPLAY_HOST_STR_LEN];
|
||||
@ -231,27 +203,17 @@ struct netplay_host
|
||||
struct netplay_host_list
|
||||
{
|
||||
struct netplay_host *hosts;
|
||||
size_t allocated;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct netplay_chat
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t frames;
|
||||
char nick[NETPLAY_NICK_LEN];
|
||||
char msg[NETPLAY_CHAT_MAX_SIZE];
|
||||
} messages[NETPLAY_CHAT_MAX_MESSAGES];
|
||||
uint32_t message_slots;
|
||||
};
|
||||
|
||||
struct netplay_chat_buffer
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t alpha;
|
||||
char nick[NETPLAY_NICK_LEN];
|
||||
char msg[NETPLAY_CHAT_MAX_SIZE];
|
||||
char nick[NETPLAY_NICK_LEN];
|
||||
char msg[NETPLAY_CHAT_MAX_SIZE];
|
||||
} messages[NETPLAY_CHAT_MAX_MESSAGES];
|
||||
};
|
||||
|
||||
@ -260,8 +222,6 @@ typedef struct
|
||||
/* NAT traversal info (if NAT traversal is used and serving) */
|
||||
struct nat_traversal_data nat_traversal_request;
|
||||
#ifdef HAVE_NETPLAYDISCOVERY
|
||||
/* Packet buffer for advertisement and responses */
|
||||
struct ad_packet ad_packet_buffer;
|
||||
/* List of discovered hosts */
|
||||
struct netplay_host_list discovered_hosts;
|
||||
#endif
|
||||
@ -272,21 +232,15 @@ typedef struct
|
||||
/* Used while Netplay is running */
|
||||
netplay_t *data;
|
||||
netplay_client_info_t *client_info;
|
||||
/* Chat messages */
|
||||
struct netplay_chat *chat;
|
||||
size_t client_info_count;
|
||||
#ifdef HAVE_NETPLAYDISCOVERY
|
||||
size_t discovered_hosts_allocated;
|
||||
/* LAN discovery sockets */
|
||||
int lan_ad_server_fd;
|
||||
int lan_ad_client_fd;
|
||||
#endif
|
||||
int room_count;
|
||||
int reannounce;
|
||||
int reping;
|
||||
int latest_ping;
|
||||
unsigned server_port_deferred;
|
||||
uint16_t mapping[RETROK_LAST];
|
||||
char server_address_deferred[256];
|
||||
char server_session_deferred[32];
|
||||
bool netplay_client_deferred;
|
||||
@ -302,101 +256,16 @@ typedef struct
|
||||
|
||||
net_driver_state_t *networking_state_get_ptr(void);
|
||||
|
||||
bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data);
|
||||
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);
|
||||
bool netplay_6to4(struct sockaddr_storage *addr);
|
||||
|
||||
int netplay_rooms_parse(const char *buf);
|
||||
|
||||
struct netplay_room* netplay_room_get(int index);
|
||||
|
||||
int netplay_rooms_get_count(void);
|
||||
|
||||
struct netplay_room *netplay_room_get(int index);
|
||||
void netplay_rooms_free(void);
|
||||
|
||||
/**
|
||||
* netplay_frontend_paused
|
||||
* @netplay : pointer to netplay object
|
||||
* @paused : true if frontend is paused
|
||||
*
|
||||
* Inform Netplay of the frontend's pause state (paused or otherwise)
|
||||
*/
|
||||
void netplay_frontend_paused(netplay_t *netplay, bool paused);
|
||||
|
||||
/**
|
||||
* netplay_toggle_play_spectate
|
||||
*
|
||||
* Toggle between play mode and spectate mode
|
||||
*/
|
||||
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
|
||||
* @serial_info : the savestate being loaded, NULL means
|
||||
* "load it yourself"
|
||||
* @save : Whether to save the provided serial_info
|
||||
* into the frame buffer
|
||||
*
|
||||
* Inform Netplay of a savestate load and send it to the other side
|
||||
**/
|
||||
void netplay_load_savestate(netplay_t *netplay,
|
||||
retro_ctx_serialize_info_t *serial_info, bool save);
|
||||
|
||||
/**
|
||||
* netplay_core_reset
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Indicate that the core has been reset to netplay peers
|
||||
**/
|
||||
void netplay_core_reset(netplay_t *netplay);
|
||||
|
||||
int16_t netplay_input_state(netplay_t *netplay,
|
||||
unsigned port, unsigned device,
|
||||
unsigned idx, unsigned id);
|
||||
|
||||
/**
|
||||
* netplay_poll:
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Polls network to see if we have anything new. If our
|
||||
* network buffer is full, we simply have to block
|
||||
* for new input data.
|
||||
*
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool netplay_poll(
|
||||
bool block_libretro_input,
|
||||
void *settings_data,
|
||||
netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_is_alive:
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Checks if input port/index is controlled by netplay or not.
|
||||
*
|
||||
* Returns: true (1) if alive, otherwise false (0).
|
||||
**/
|
||||
bool netplay_is_alive(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_should_skip:
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* If we're fast-forward replaying to resync, check if we
|
||||
* should actually show frame.
|
||||
*
|
||||
* Returns: bool (1) if we should skip this frame, otherwise
|
||||
* false (0).
|
||||
**/
|
||||
bool netplay_should_skip(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* init_netplay
|
||||
* @server : server address to connect to (client only)
|
||||
@ -410,33 +279,22 @@ bool netplay_should_skip(netplay_t *netplay);
|
||||
* Returns: true (1) if successful, otherwise false (0).
|
||||
**/
|
||||
bool init_netplay(const char *server, unsigned port, const char *mitm_session);
|
||||
|
||||
bool init_netplay_deferred(const char *server, unsigned port, const char *mitm_session);
|
||||
|
||||
bool init_netplay_deferred(const char *server, unsigned port,
|
||||
const char *mitm_session);
|
||||
void deinit_netplay(void);
|
||||
|
||||
void video_frame_net(const void *data, unsigned width,
|
||||
unsigned height, size_t pitch);
|
||||
void audio_sample_net(int16_t left, int16_t right);
|
||||
size_t audio_sample_batch_net(const int16_t *data, size_t frames);
|
||||
int16_t input_state_net(unsigned port, unsigned device,
|
||||
unsigned idx, unsigned id);
|
||||
bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data);
|
||||
|
||||
#ifdef HAVE_NETPLAYDISCOVERY
|
||||
/** Initialize Netplay discovery */
|
||||
bool init_netplay_discovery(void);
|
||||
|
||||
/** Deinitialize and free Netplay discovery */
|
||||
void deinit_netplay_discovery(void);
|
||||
|
||||
/** Discovery control */
|
||||
bool netplay_discovery_driver_ctl(
|
||||
enum rarch_netplay_discovery_ctl_state state, void *data);
|
||||
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);
|
||||
bool netplay_6to4(struct sockaddr_storage *addr);
|
||||
|
||||
extern const mitm_server_t netplay_mitm_server_list[NETPLAY_MITM_SERVERS];
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,25 +20,30 @@
|
||||
#define __RARCH_NETPLAY_PRIVATE_H
|
||||
|
||||
#include "netplay.h"
|
||||
#include "netplay_protocol.h"
|
||||
|
||||
#include <libretro.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <streams/trans_stream.h>
|
||||
|
||||
#include "../../retroarch_types.h"
|
||||
|
||||
#define RARCH_DEFAULT_PORT 55435
|
||||
#define RARCH_DEFAULT_NICK "Anonymous"
|
||||
|
||||
#define NETPLAY_PASS_LEN 128
|
||||
#define NETPLAY_PASS_HASH_LEN 64 /* length of a SHA-256 hash */
|
||||
|
||||
#define MAX_SERVER_STALL_TIME_USEC (5*1000*1000)
|
||||
#define MAX_CLIENT_STALL_TIME_USEC (10*1000*1000)
|
||||
#define CATCH_UP_CHECK_TIME_USEC (500*1000)
|
||||
#define MAX_RETRIES 16
|
||||
#define RETRY_MS 500
|
||||
#define MAX_INPUT_DEVICES 16
|
||||
#define MAX_SERVER_STALL_TIME_USEC (5*1000*1000)
|
||||
#define MAX_CLIENT_STALL_TIME_USEC (10*1000*1000)
|
||||
#define CATCH_UP_CHECK_TIME_USEC (500*1000)
|
||||
#define MAX_RETRIES 16
|
||||
#define RETRY_MS 500
|
||||
#define MAX_INPUT_DEVICES 16
|
||||
|
||||
/* We allow only 32 clients to fit into a 32-bit bitmap */
|
||||
#define MAX_CLIENTS 32
|
||||
typedef uint32_t client_bitmap_t;
|
||||
#define MAX_CLIENTS 32
|
||||
|
||||
/* Because the callback keyboard reverses some assumptions, when the keyboard
|
||||
* callbacks are in use, we assign a pseudodevice for it */
|
||||
@ -63,8 +68,9 @@ typedef uint32_t client_bitmap_t;
|
||||
/* Mapping of serialization quirks to netplay quirks. */
|
||||
#define NETPLAY_QUIRK_MAP_UNDERSTOOD (\
|
||||
RETRO_SERIALIZATION_QUIRK_INCOMPLETE |\
|
||||
RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE |\
|
||||
RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE |\
|
||||
RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE |\
|
||||
RETRO_SERIALIZATION_QUIRK_FRONT_VARIABLE_SIZE |\
|
||||
RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION |\
|
||||
RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT |\
|
||||
RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT \
|
||||
@ -89,6 +95,18 @@ typedef uint32_t client_bitmap_t;
|
||||
#define NETPLAY_COMPRESSION_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
/* The keys supported by netplay */
|
||||
enum netplay_keys
|
||||
{
|
||||
NETPLAY_KEY_UNKNOWN = 0,
|
||||
#define K(k) NETPLAY_KEY_ ## k,
|
||||
#define KL(k,l) K(k)
|
||||
#include "netplay_keys.h"
|
||||
#undef KL
|
||||
#undef K
|
||||
NETPLAY_KEY_LAST
|
||||
};
|
||||
|
||||
enum netplay_cmd
|
||||
{
|
||||
/* Basic commands */
|
||||
@ -194,11 +212,11 @@ enum netplay_cmd
|
||||
NETPLAY_CMD_SETTING_INPUT_LATENCY_FRAMES = 0x2001
|
||||
};
|
||||
|
||||
#define NETPLAY_CMD_SYNC_BIT_PAUSED (1U<<31)
|
||||
#define NETPLAY_CMD_PLAY_BIT_SLAVE (1U<<31)
|
||||
#define NETPLAY_CMD_MODE_BIT_YOU (1U<<31)
|
||||
#define NETPLAY_CMD_MODE_BIT_PLAYING (1U<<30)
|
||||
#define NETPLAY_CMD_MODE_BIT_SLAVE (1U<<29)
|
||||
#define NETPLAY_CMD_SYNC_BIT_PAUSED (1U<<31)
|
||||
#define NETPLAY_CMD_PLAY_BIT_SLAVE (1U<<31)
|
||||
#define NETPLAY_CMD_MODE_BIT_YOU (1U<<31)
|
||||
#define NETPLAY_CMD_MODE_BIT_PLAYING (1U<<30)
|
||||
#define NETPLAY_CMD_MODE_BIT_SLAVE (1U<<29)
|
||||
|
||||
/* These are the reasons given for mode changes to be rejected */
|
||||
enum netplay_cmd_mode_reasons
|
||||
@ -224,22 +242,22 @@ enum rarch_netplay_share_preference
|
||||
{
|
||||
/* Prefer not to share, shouldn't be set
|
||||
as a sharing mode for an shared device */
|
||||
NETPLAY_SHARE_NO_SHARING = 0x0,
|
||||
NETPLAY_SHARE_NO_SHARING = 0x00,
|
||||
|
||||
/* No preference. Only for requests.
|
||||
Set if sharing is requested but either
|
||||
* digital or analog doesn't have a preference. */
|
||||
NETPLAY_SHARE_NO_PREFERENCE = 0x1,
|
||||
NETPLAY_SHARE_NO_PREFERENCE = 0x01,
|
||||
|
||||
/* For digital devices */
|
||||
NETPLAY_SHARE_DIGITAL_BITS = 0x1C,
|
||||
NETPLAY_SHARE_DIGITAL_OR = 0x4,
|
||||
NETPLAY_SHARE_DIGITAL_XOR = 0x8,
|
||||
NETPLAY_SHARE_DIGITAL_VOTE = 0xC,
|
||||
NETPLAY_SHARE_DIGITAL_BITS = 0x1C,
|
||||
NETPLAY_SHARE_DIGITAL_OR = 0x04,
|
||||
NETPLAY_SHARE_DIGITAL_XOR = 0x08,
|
||||
NETPLAY_SHARE_DIGITAL_VOTE = 0x0C,
|
||||
|
||||
/* For analog devices */
|
||||
NETPLAY_SHARE_ANALOG_BITS = 0xE0,
|
||||
NETPLAY_SHARE_ANALOG_MAX = 0x20,
|
||||
NETPLAY_SHARE_ANALOG_BITS = 0xE0,
|
||||
NETPLAY_SHARE_ANALOG_MAX = 0x20,
|
||||
NETPLAY_SHARE_ANALOG_AVERAGE = 0x40
|
||||
};
|
||||
|
||||
@ -300,7 +318,7 @@ struct delta_frame
|
||||
|
||||
/* The simulated input. is_real here means the simulation is done, i.e.,
|
||||
* it's a real simulation, not real input. */
|
||||
netplay_input_state_t simlated_input[MAX_INPUT_DEVICES];
|
||||
netplay_input_state_t simulated_input[MAX_INPUT_DEVICES];
|
||||
|
||||
/* The serialized state of the core at this frame, before input */
|
||||
void *state;
|
||||
@ -339,14 +357,18 @@ struct netplay_connection
|
||||
/* Timer used to estimate a connection's latency */
|
||||
retro_time_t ping_timer;
|
||||
|
||||
/* Address of peer */
|
||||
struct sockaddr_storage addr;
|
||||
|
||||
/* Buffers for sending and receiving data */
|
||||
struct socket_buffer send_packet_buffer, recv_packet_buffer;
|
||||
struct socket_buffer send_packet_buffer;
|
||||
struct socket_buffer recv_packet_buffer;
|
||||
|
||||
/* fd associated with this connection */
|
||||
int fd;
|
||||
/* What compression does this peer support? */
|
||||
uint32_t compression_supported;
|
||||
|
||||
/* Salt associated with password transaction */
|
||||
uint32_t salt;
|
||||
|
||||
/* Which netplay protocol is this connection running? */
|
||||
uint32_t netplay_protocol;
|
||||
|
||||
/* If the mode is a DELAYED_DISCONNECT or SPECTATOR,
|
||||
* the transmission of the mode change may have to
|
||||
@ -355,43 +377,37 @@ struct netplay_connection
|
||||
* is active. */
|
||||
uint32_t delay_frame;
|
||||
|
||||
/* What compression does this peer support? */
|
||||
uint32_t compression_supported;
|
||||
|
||||
/* For the server: When was the last time we requested
|
||||
* this client to stall?
|
||||
* For the client: How many frames of stall do we have left? */
|
||||
uint32_t stall_frame;
|
||||
|
||||
/* Salt associated with password transaction */
|
||||
uint32_t salt;
|
||||
|
||||
/* Which netplay protocol is this connection running? */
|
||||
uint32_t netplay_protocol;
|
||||
|
||||
/* What latency is this connection running on?
|
||||
* Network latency has limited precision as we estimate it
|
||||
* once every pre-frame. */
|
||||
int32_t ping;
|
||||
|
||||
/* Is this connection stalling? */
|
||||
enum rarch_netplay_stall_reason stall;
|
||||
/* fd associated with this connection */
|
||||
int fd;
|
||||
|
||||
/* Mode of the connection */
|
||||
enum rarch_netplay_connection_mode mode;
|
||||
|
||||
/* Is this connection stalling? */
|
||||
enum rarch_netplay_stall_reason stall;
|
||||
|
||||
/* Nickname of peer */
|
||||
char nick[NETPLAY_NICK_LEN];
|
||||
|
||||
/* Is this connection buffer in use? */
|
||||
bool active;
|
||||
|
||||
/* Is this player paused? */
|
||||
bool paused;
|
||||
|
||||
/* Is this connection allowed to play (server only)? */
|
||||
bool can_play;
|
||||
|
||||
/* Is this connection buffer in use? */
|
||||
bool active;
|
||||
|
||||
/* Did we request a ping response? */
|
||||
bool ping_requested;
|
||||
};
|
||||
@ -400,8 +416,8 @@ struct netplay_connection
|
||||
struct compression_transcoder
|
||||
{
|
||||
const struct trans_stream_backend *compression_backend;
|
||||
void *compression_stream;
|
||||
const struct trans_stream_backend *decompression_backend;
|
||||
void *compression_stream;
|
||||
void *decompression_stream;
|
||||
};
|
||||
|
||||
@ -423,42 +439,52 @@ struct netplay_mitm_pending
|
||||
int fds[NETPLAY_MITM_MAX_PENDING];
|
||||
};
|
||||
|
||||
struct netplay_chat
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t frames;
|
||||
char nick[NETPLAY_NICK_LEN];
|
||||
char msg[NETPLAY_CHAT_MAX_SIZE];
|
||||
} messages[NETPLAY_CHAT_MAX_MESSAGES];
|
||||
};
|
||||
|
||||
struct netplay
|
||||
{
|
||||
/* Quirks in the savestate implementation */
|
||||
uint64_t quirks;
|
||||
|
||||
/* We stall if we're far enough ahead that we
|
||||
* couldn't transparently rewind.
|
||||
* To know if we could transparently rewind,
|
||||
* we need to know how long running a frame takes.
|
||||
* We record that every frame and get a running (window) average. */
|
||||
retro_time_t frame_run_time[NETPLAY_FRAME_RUN_TIME_WINDOW];
|
||||
retro_time_t frame_run_time_sum;
|
||||
retro_time_t frame_run_time_avg;
|
||||
|
||||
/* When did we start falling behind? */
|
||||
retro_time_t catch_up_time;
|
||||
/* How long have we been stalled? */
|
||||
retro_time_t stall_time;
|
||||
|
||||
/* We stall if we're far enough ahead that we
|
||||
* couldn't transparently rewind.
|
||||
* To know if we could transparently rewind,
|
||||
* we need to know how long running a frame takes.
|
||||
* We record that every frame and get a running (window) average. */
|
||||
retro_time_t frame_run_time[NETPLAY_FRAME_RUN_TIME_WINDOW];
|
||||
retro_time_t frame_run_time_sum, frame_run_time_avg;
|
||||
|
||||
struct retro_callbacks cbs;
|
||||
|
||||
/* Compression transcoder */
|
||||
struct compression_transcoder compress_nil,
|
||||
compress_zlib;
|
||||
struct compression_transcoder compress_nil;
|
||||
struct compression_transcoder compress_zlib;
|
||||
|
||||
/* MITM session id */
|
||||
mitm_id_t mitm_session_id;
|
||||
|
||||
struct netplay_connection one_connection; /* Client only */
|
||||
/* All of our connections */
|
||||
struct netplay_connection *connections;
|
||||
/* Chat messages */
|
||||
struct netplay_chat chat;
|
||||
|
||||
/* MITM connection handler */
|
||||
struct netplay_mitm_pending *mitm_pending;
|
||||
|
||||
/* Our local socket info */
|
||||
struct addrinfo *addr;
|
||||
/* All of our connections */
|
||||
struct netplay_connection *connections;
|
||||
|
||||
struct delta_frame *buffer;
|
||||
|
||||
@ -475,21 +501,21 @@ struct netplay
|
||||
|
||||
/* The frame we're currently inputting */
|
||||
size_t self_ptr;
|
||||
/* The frame we're currently running, which may be
|
||||
/* The frame we're currently running, which may be
|
||||
* behind the frame we're currently inputting if
|
||||
* we're using input latency */
|
||||
size_t run_ptr;
|
||||
/* The first frame at which some data might be unreliable */
|
||||
size_t other_ptr;
|
||||
/* Pointer to the first frame for which we're missing
|
||||
/* Pointer to the first frame for which we're missing
|
||||
* the data of at least one connected player excluding ourself.
|
||||
* Generally, other_ptr <= unread_ptr <= self_ptr,
|
||||
* but unread_ptr can get ahead of self_ptr if the peer
|
||||
* Generally, other_ptr <= unread_ptr <= self_ptr,
|
||||
* but unread_ptr can get ahead of self_ptr if the peer
|
||||
* is running fast. */
|
||||
size_t unread_ptr;
|
||||
/* Pointer to the next frame to read from each client */
|
||||
size_t read_ptr[MAX_CLIENTS];
|
||||
/* Pointer to the next frame to read from the server
|
||||
/* Pointer to the next frame to read from the server
|
||||
* (as it might not be a player but still synchronizes)
|
||||
*/
|
||||
size_t server_ptr;
|
||||
@ -499,9 +525,6 @@ struct netplay
|
||||
/* Pseudo random seed */
|
||||
unsigned long simple_rand_next;
|
||||
|
||||
/* TCP connection for listening (server only) */
|
||||
int listen_fd;
|
||||
|
||||
/* Our client number */
|
||||
uint32_t self_client_num;
|
||||
|
||||
@ -516,15 +539,11 @@ struct netplay
|
||||
uint32_t client_devices[MAX_CLIENTS];
|
||||
|
||||
/* For each device, the bitmap of clients connected */
|
||||
client_bitmap_t device_clients[MAX_INPUT_DEVICES];
|
||||
uint32_t device_clients[MAX_INPUT_DEVICES];
|
||||
|
||||
/* Our own device bitmap */
|
||||
uint32_t self_devices;
|
||||
|
||||
/* Number of desync operations we're currently performing.
|
||||
* If set, we don't attempt to stay in sync. */
|
||||
uint32_t desync;
|
||||
|
||||
/* The device types for every connected device.
|
||||
* We store them and ignore any menu changes,
|
||||
* as netplay needs fixed devices. */
|
||||
@ -538,31 +557,46 @@ struct netplay
|
||||
uint32_t server_frame_count;
|
||||
uint32_t replay_frame_count;
|
||||
|
||||
int frame_run_time_ptr;
|
||||
|
||||
/* Counter for timeouts */
|
||||
unsigned timeout_cnt;
|
||||
|
||||
/* Latency frames; positive to hide network latency,
|
||||
* negative to hide input latency */
|
||||
int input_latency_frames;
|
||||
|
||||
/* Frequency with which to check CRCs */
|
||||
int check_frames;
|
||||
|
||||
/* How far behind did we fall? */
|
||||
uint32_t catch_up_behind;
|
||||
|
||||
/* Number of desync operations we're currently performing.
|
||||
* If set, we don't attempt to stay in sync. */
|
||||
uint32_t desync;
|
||||
|
||||
/* Host settings */
|
||||
int32_t input_latency_frames_min;
|
||||
int32_t input_latency_frames_max;
|
||||
|
||||
/* Are we stalled? */
|
||||
enum rarch_netplay_stall_reason stall;
|
||||
/* Counter for timeouts */
|
||||
unsigned timeout_cnt;
|
||||
|
||||
/* TCP connection for listening (server only) */
|
||||
int listen_fd;
|
||||
|
||||
int frame_run_time_ptr;
|
||||
|
||||
/* Frequency with which to check CRCs */
|
||||
int check_frames;
|
||||
|
||||
/* Latency frames; positive to hide network latency,
|
||||
* negative to hide input latency */
|
||||
int input_latency_frames;
|
||||
|
||||
int reannounce;
|
||||
|
||||
int reping;
|
||||
|
||||
/* Our mode and status */
|
||||
enum rarch_netplay_connection_mode self_mode;
|
||||
|
||||
/* Are we stalled? */
|
||||
enum rarch_netplay_stall_reason stall;
|
||||
|
||||
/* Keyboard mapping (network and host) */
|
||||
uint16_t mapping_hton[RETROK_LAST];
|
||||
uint16_t mapping_ntoh[NETPLAY_KEY_LAST];
|
||||
|
||||
/* TCP port (only set if serving) */
|
||||
uint16_t tcp_port;
|
||||
uint16_t ext_tcp_port;
|
||||
@ -573,8 +607,6 @@ struct netplay
|
||||
/* Our nickname */
|
||||
char nick[NETPLAY_NICK_LEN];
|
||||
|
||||
bool nat_traversal;
|
||||
|
||||
/* Set to true if we have a device that most cores
|
||||
* translate to "up/down" actions, typically a keyboard.
|
||||
* We need to keep track of this because with such a device,
|
||||
@ -583,11 +615,30 @@ struct netplay
|
||||
* up/down states will proceed as expected. */
|
||||
bool have_updown_device;
|
||||
|
||||
/* If true, never progress without peer input
|
||||
* (stateless/rewindless mode) */
|
||||
bool stateless_mode;
|
||||
|
||||
/* Are we the server? */
|
||||
bool is_server;
|
||||
|
||||
bool nat_traversal;
|
||||
|
||||
/* Have we checked whether CRCs are valid at all? */
|
||||
bool crc_validity_checked;
|
||||
|
||||
/* Are they valid? */
|
||||
bool crcs_valid;
|
||||
|
||||
/* Netplay pausing */
|
||||
bool local_paused;
|
||||
bool remote_paused;
|
||||
|
||||
/* Are we replaying old frames? */
|
||||
bool is_replay;
|
||||
|
||||
/* We don't want to poll several times on a frame. */
|
||||
bool can_poll;
|
||||
/* Opposite of stalling, should we be catching up? */
|
||||
bool catch_up;
|
||||
|
||||
/* Force a rewind to other_frame_count/other_ptr.
|
||||
* This is for synchronized events, such as restarting
|
||||
@ -603,33 +654,17 @@ struct netplay
|
||||
/* Have we requested a savestate as a sync point? */
|
||||
bool savestate_request_outstanding;
|
||||
|
||||
/* Netplay pausing */
|
||||
bool local_paused;
|
||||
bool remote_paused;
|
||||
|
||||
/* If true, never progress without peer input
|
||||
* (stateless/rewindless mode) */
|
||||
bool stateless_mode;
|
||||
|
||||
/* Opposite of stalling, should we be catching up? */
|
||||
bool catch_up;
|
||||
|
||||
/* Have we checked whether CRCs are valid at all? */
|
||||
bool crc_validity_checked;
|
||||
|
||||
/* Are they valid? */
|
||||
bool crcs_valid;
|
||||
|
||||
/* Are we the server? */
|
||||
bool is_server;
|
||||
|
||||
/* Are we the connected? */
|
||||
bool is_connected;
|
||||
|
||||
/* Host settings */
|
||||
bool allow_pausing;
|
||||
};
|
||||
|
||||
void video_frame_net(const void *data,
|
||||
unsigned width, unsigned height, size_t pitch);
|
||||
void audio_sample_net(int16_t left, int16_t right);
|
||||
size_t audio_sample_batch_net(const int16_t *data, size_t frames);
|
||||
int16_t input_state_net(unsigned port, unsigned device,
|
||||
unsigned idx, unsigned id);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-BUF.C
|
||||
**************************************************************/
|
||||
@ -699,69 +734,22 @@ bool netplay_delta_frame_ready(netplay_t *netplay,
|
||||
struct delta_frame *delta,
|
||||
uint32_t frame);
|
||||
|
||||
/**
|
||||
* netplay_input_state_for
|
||||
*
|
||||
* Get an input state for a particular client
|
||||
*/
|
||||
netplay_input_state_t netplay_input_state_for(
|
||||
netplay_input_state_t *list,
|
||||
uint32_t client_num, size_t size,
|
||||
bool must_create, bool must_not_create);
|
||||
|
||||
/**
|
||||
* netplay_expected_input_size
|
||||
*
|
||||
* Size in words for a given set of devices.
|
||||
*/
|
||||
uint32_t netplay_expected_input_size(netplay_t *netplay,
|
||||
uint32_t devices);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-FRONTEND.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* input_poll_net
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Poll the network if necessary.
|
||||
*/
|
||||
void input_poll_net(void);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-HANDSHAKE.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_handshake_init_send
|
||||
*
|
||||
* Initialize our handshake and send the first
|
||||
* part of the handshake protocol.
|
||||
*/
|
||||
bool netplay_handshake_init_send(netplay_t *netplay,
|
||||
struct netplay_connection *connection, uint32_t protocol);
|
||||
|
||||
/**
|
||||
* netplay_handshake
|
||||
*
|
||||
* Data receiver for all handshake states.
|
||||
*/
|
||||
bool netplay_handshake(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input);
|
||||
void input_poll_net(netplay_t *netplay);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-INIT.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_try_init_serialization
|
||||
*
|
||||
* Try to initialize serialization. For quirky cores.
|
||||
*
|
||||
* Returns true if serialization is now ready, false otherwise.
|
||||
*/
|
||||
bool netplay_try_init_serialization(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_wait_and_init_serialization
|
||||
*
|
||||
@ -772,59 +760,10 @@ bool netplay_try_init_serialization(netplay_t *netplay);
|
||||
*/
|
||||
bool netplay_wait_and_init_serialization(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_new:
|
||||
* @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.
|
||||
* @nat_traversal : If true, attempt NAT traversal.
|
||||
* @nick : Nickname of user.
|
||||
* @quirks : Netplay quirks required for this session.
|
||||
*
|
||||
* Creates a new netplay handle. A NULL server means we're
|
||||
* hosting.
|
||||
*
|
||||
* Returns: new netplay data.
|
||||
*/
|
||||
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,
|
||||
uint64_t quirks);
|
||||
|
||||
/**
|
||||
* netplay_free
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Frees netplay data/
|
||||
*/
|
||||
void netplay_free(netplay_t *netplay);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-IO.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_hangup:
|
||||
*
|
||||
* Disconnects an active Netplay connection due to an error
|
||||
*/
|
||||
void netplay_hangup(netplay_t *netplay,
|
||||
struct netplay_connection *connection);
|
||||
|
||||
/**
|
||||
* netplay_delayed_state_change:
|
||||
*
|
||||
* Handle any pending state changes which are ready as
|
||||
* of the beginning of the current frame.
|
||||
*/
|
||||
void netplay_delayed_state_change(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_send_cur_input
|
||||
*
|
||||
@ -866,85 +805,20 @@ void netplay_send_raw_cmd_all(netplay_t *netplay,
|
||||
bool netplay_cmd_mode(netplay_t *netplay,
|
||||
enum rarch_netplay_connection_mode mode);
|
||||
|
||||
/**
|
||||
* netplay_poll_net_input
|
||||
*
|
||||
* Poll input from the network
|
||||
*/
|
||||
int netplay_poll_net_input(netplay_t *netplay, bool block);
|
||||
|
||||
/**
|
||||
* netplay_handle_slaves
|
||||
*
|
||||
* Handle any slave connections
|
||||
*/
|
||||
void netplay_handle_slaves(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_init_nat_traversal
|
||||
*
|
||||
* Initialize the NAT traversal library and try to open a port
|
||||
*/
|
||||
void netplay_init_nat_traversal(netplay_t *netplay);
|
||||
|
||||
void netplay_deinit_nat_traversal(void);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-KEYBOARD.C
|
||||
**************************************************************/
|
||||
|
||||
/* The mapping of keys from libretro (host) to netplay (network) */
|
||||
uint32_t netplay_key_hton(unsigned key);
|
||||
|
||||
/* Because the hton keymapping has to be generated,
|
||||
* call this before using netplay_key_hton */
|
||||
void netplay_key_hton_init(void);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-SYNC.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_update_unread_ptr
|
||||
*
|
||||
* Update the global unread_ptr and unread_frame_count to
|
||||
* correspond to the earliest unread frame count of any
|
||||
* connected player.
|
||||
*/
|
||||
void netplay_update_unread_ptr(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_resolve_input
|
||||
* @netplay : pointer to netplay object
|
||||
* @sim_ptr : frame pointer for which to resolve input
|
||||
* @resim : are we resimulating, or simulating this
|
||||
* frame for the first time?
|
||||
*
|
||||
* "Simulate" input by assuming it hasn't changed since the
|
||||
* last read input.
|
||||
* Returns true if the resolved input changed from the
|
||||
* last time it was resolved.
|
||||
*/
|
||||
bool netplay_resolve_input(netplay_t *netplay,
|
||||
size_t sim_ptr, bool resim);
|
||||
|
||||
/**
|
||||
* netplay_sync_pre_frame
|
||||
* netplay_load_savestate
|
||||
* @netplay : pointer to netplay object
|
||||
* @disconnect : disconnect netplay
|
||||
* @serial_info : the savestate being loaded, NULL means
|
||||
* "load it yourself"
|
||||
* @save : Whether to save the provided serial_info
|
||||
* into the frame buffer
|
||||
*
|
||||
* Pre-frame for Netplay synchronization.
|
||||
*/
|
||||
bool netplay_sync_pre_frame(netplay_t *netplay, bool *disconnect);
|
||||
|
||||
/**
|
||||
* netplay_sync_post_frame
|
||||
* @netplay : pointer to netplay object
|
||||
* @stalled : true if we're currently stalled
|
||||
*
|
||||
* Post-frame for Netplay synchronization.
|
||||
* We check if we have new input and replay from recorded input.
|
||||
*/
|
||||
void netplay_sync_post_frame(netplay_t *netplay, bool stalled);
|
||||
|
||||
* Inform Netplay of a savestate load and send it to the other side
|
||||
**/
|
||||
void netplay_load_savestate(netplay_t *netplay,
|
||||
retro_ctx_serialize_info_t *serial_info, bool save);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user