Say goodbye to spectator mode (for now)

This commit is contained in:
Gregor Richards 2016-12-09 23:04:39 -05:00
parent 4768970d52
commit 9b2270f5d4
12 changed files with 18 additions and 405 deletions

View File

@ -1123,7 +1123,6 @@ ifeq ($(HAVE_NETWORKING), 1)
# Netplay
DEFINES += -DHAVE_NETWORK_CMD
OBJ += network/netplay/netplay_net.o \
network/netplay/netplay_spectate.o \
network/netplay/netplay_common.o \
network/netplay/netplay_discovery.o \
network/netplay/netplay_buf.o \

View File

@ -1227,8 +1227,7 @@ static void command_event_load_auto_state(void)
global_t *global = global_get_ptr();
#ifdef HAVE_NETWORKING
if ( netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL)
&& !settings->netplay.is_spectate)
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL))
return;
#endif
@ -2362,7 +2361,7 @@ bool command_event(enum event_command cmd, void *data)
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
#ifdef HAVE_NETWORKING
if (!init_netplay(
settings->netplay.is_spectate, data, settings->netplay.server,
data, settings->netplay.server,
settings->netplay.port))
return false;
#endif

View File

@ -822,7 +822,6 @@ static int populate_settings_bool(settings_t *settings, struct config_bool_setti
SETTING_BOOL("network_remote_enable", &settings->network_remote_enable, false, false /* TODO */, false);
#endif
#ifdef HAVE_NETWORKING
SETTING_BOOL("netplay_spectator_mode_enable",&settings->netplay.is_spectate, false, false /* TODO */, false);
SETTING_BOOL("netplay_nat_traversal", &settings->netplay.nat_traversal, true, true, false);
#endif
SETTING_BOOL("block_sram_overwrite", &settings->block_sram_overwrite, true, block_sram_overwrite, false);
@ -1807,13 +1806,6 @@ static bool config_load_file(const char *path, bool set_defaults,
if (!rarch_ctl(RARCH_CTL_IS_FORCE_FULLSCREEN, NULL))
CONFIG_GET_BOOL_BASE(conf, settings, video.fullscreen, "video_fullscreen");
#ifdef HAVE_NETWORKING
if (!retroarch_override_setting_is_set(RARCH_OVERRIDE_SETTING_NETPLAY_MODE, NULL))
{
CONFIG_GET_BOOL_BASE(conf, settings, netplay.is_spectate,
"netplay_spectator_mode_enable");
}
#endif
#ifdef HAVE_NETWORKGAMEPAD
for (i = 0; i < MAX_USERS; i++)
{

View File

@ -403,7 +403,6 @@ typedef struct settings
unsigned port;
unsigned delay_frames;
unsigned check_frames;
bool is_spectate;
bool swap_input;
bool nat_traversal;
} netplay;

View File

@ -4697,10 +4697,6 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES,
PARSE_ONLY_UINT, false) != -1)
count++;
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE,
PARSE_ONLY_BOOL, false) != -1)
count++;
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT,
PARSE_ONLY_BOOL, false) != -1)

View File

@ -1719,11 +1719,6 @@ void general_write_handler(void *data)
case MENU_ENUM_LABEL_NETPLAY_MODE:
#ifdef HAVE_NETWORKING
retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_NETPLAY_MODE, NULL);
#endif
break;
case MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE:
#ifdef HAVE_NETWORKING
retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_NETPLAY_MODE, NULL);
#endif
break;
case MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES:
@ -5610,21 +5605,6 @@ static bool setting_append_list(
menu_settings_list_current_add_range(list, list_info, 0, 10, 1, true, false);
settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED);
CONFIG_BOOL(
list, list_info,
&settings->netplay.is_spectate,
MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE,
MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE,
false,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
CONFIG_BOOL(
list, list_info,
&settings->netplay.nat_traversal,

View File

@ -61,7 +61,7 @@ static void announce_nat_traversal(netplay_t *netplay);
#endif
static int init_tcp_connection(const struct addrinfo *res,
bool server, bool spectate,
bool server,
struct sockaddr *other_addr, socklen_t addr_size)
{
bool ret = true;
@ -114,7 +114,7 @@ static int init_tcp_connection(const struct addrinfo *res,
}
#endif
if ( !socket_bind(fd, (void*)res) ||
listen(fd, spectate ? MAX_SPECTATORS : 1) < 0)
listen(fd, 1024) < 0)
{
ret = false;
goto end;
@ -132,7 +132,7 @@ end:
}
static bool init_tcp_socket(netplay_t *netplay, void *direct_host,
const char *server, uint16_t port, bool spectate)
const char *server, uint16_t port)
{
char port_buf[16];
bool ret = false;
@ -206,7 +206,6 @@ static bool init_tcp_socket(netplay_t *netplay, void *direct_host,
int fd = init_tcp_connection(
tmp_info,
direct_host || server,
netplay->spectate.enabled,
(struct sockaddr*)&sad,
sizeof(sad));
@ -261,7 +260,7 @@ static bool init_socket(netplay_t *netplay, void *direct_host, const char *serve
if (!network_init())
return false;
if (!init_tcp_socket(netplay, direct_host, server, port, netplay->spectate.enabled))
if (!init_tcp_socket(netplay, direct_host, server, port))
return false;
if (netplay->is_server && netplay->nat_traversal)
@ -349,8 +348,7 @@ static bool netplay_can_poll(netplay_t *netplay)
* finishing the initial handshake */
static void send_input(netplay_t *netplay, struct netplay_connection *connection)
{
if (!netplay->spectate.enabled && /* Spectate sends in its own way */
netplay->self_mode == NETPLAY_CONNECTION_PLAYING &&
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING &&
connection->mode >= NETPLAY_CONNECTION_CONNECTED)
{
netplay->input_packet_buffer[2] = htonl(netplay->self_frame_count);
@ -1434,7 +1432,6 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
* @delay_frames : Amount of delay frames.
* @check_frames : Frequency with which to check CRCs.
* @cb : Libretro callbacks.
* @spectate : If true, enable spectator mode.
* @nat_traversal : If true, attempt NAT traversal.
* @nick : Nickname of user.
* @quirks : Netplay quirks required for this session.
@ -1446,7 +1443,7 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
**/
netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
unsigned delay_frames, unsigned check_frames,
const struct retro_callbacks *cb, bool spectate, bool nat_traversal,
const struct retro_callbacks *cb, bool nat_traversal,
const char *nick, uint64_t quirks)
{
netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay));
@ -1457,7 +1454,6 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
netplay->tcp_port = port;
netplay->cbs = *cb;
netplay->port = server ? 0 : 1;
netplay->spectate.enabled = spectate;
netplay->is_server = server == NULL;
netplay->nat_traversal = netplay->is_server ? nat_traversal : false;
netplay->delay_frames = delay_frames;
@ -1481,10 +1477,7 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
strlcpy(netplay->nick, nick[0] ? nick : RARCH_DEFAULT_NICK, sizeof(netplay->nick));
if(spectate)
netplay->net_cbs = netplay_get_cbs_spectate();
else
netplay->net_cbs = netplay_get_cbs_net();
netplay->net_cbs = netplay_get_cbs_net();
if (!init_socket(netplay, direct_host, server, port))
{
@ -1620,15 +1613,6 @@ void netplay_free(netplay_t *netplay)
}
}
if (netplay->spectate.enabled)
{
for (i = 0; i < MAX_SPECTATORS; i++)
if (netplay->spectate.fds[i] >= 0)
socket_close(netplay->spectate.fds[i]);
free(netplay->spectate.input);
}
if (netplay->connections && netplay->connections != &netplay->one_connection)
free(netplay->connections);
@ -1897,7 +1881,7 @@ void deinit_netplay(void)
* Returns: true (1) if successful, otherwise false (0).
**/
bool init_netplay(bool is_spectate, void *direct_host, const char *server, unsigned port)
bool init_netplay(void *direct_host, const char *server, unsigned port)
{
struct retro_callbacks cbs = {0};
settings_t *settings = config_get_ptr();
@ -1953,7 +1937,7 @@ bool init_netplay(bool is_spectate, void *direct_host, const char *server, unsig
netplay_is_client ? server : NULL,
port ? port : RARCH_DEFAULT_PORT,
settings->netplay.delay_frames, settings->netplay.check_frames, &cbs,
is_spectate, settings->netplay.nat_traversal, settings->username,
settings->netplay.nat_traversal, settings->username,
quirks);
if (netplay_data)

View File

@ -58,7 +58,6 @@ size_t audio_sample_batch_net(const int16_t *data, size_t frames);
/**
* init_netplay
* @is_spectate : true if running in spectate mode
* @server : server address to connect to (client only)
* @port : TCP port to host on/connect to
*
@ -68,7 +67,7 @@ size_t audio_sample_batch_net(const int16_t *data, size_t frames);
*
* Returns: true (1) if successful, otherwise false (0).
**/
bool init_netplay(bool is_spectate, void *direct_host, const char *server, unsigned port);
bool init_netplay(void *direct_host, const char *server, unsigned port);
void deinit_netplay(void);

View File

@ -466,13 +466,6 @@ bool netplay_is_server(netplay_t* netplay)
return netplay->is_server;
}
bool netplay_is_spectate(netplay_t* netplay)
{
if (!netplay)
return false;
return netplay->spectate.enabled;
}
bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta, uint32_t frame)
{
void *remember_state;

View File

@ -35,7 +35,6 @@
#endif
#define WORDS_PER_FRAME 4 /* Allows us to send 128 bits worth of state per frame. */
#define MAX_SPECTATORS 16
#define RARCH_DEFAULT_PORT 55435
#define RARCH_DEFAULT_NICK "Anonymous"
@ -253,6 +252,9 @@ struct netplay_connection
struct netplay
{
/* Are we the server? */
bool is_server;
/* Our nickname */
char nick[32];
@ -350,24 +352,12 @@ struct netplay
/* A buffer for outgoing input packets. */
uint32_t input_packet_buffer[2 + WORDS_PER_FRAME];
/* And socket info */
/* Our local socket info */
struct addrinfo *addr;
struct sockaddr_storage their_addr;
bool has_client_addr;
/* Counter for timeouts */
unsigned timeout_cnt;
/* Spectating. */
struct {
bool enabled;
int fds[MAX_SPECTATORS];
uint32_t frames[MAX_SPECTATORS];
uint16_t *input;
size_t input_ptr;
size_t input_sz;
} spectate;
bool is_server;
/* User flipping
* Flipping state. If frame >= flip_frame, we apply the flip.
* If not, we apply the opposite, effectively creating a trigger point. */
@ -400,7 +390,6 @@ void input_poll_net(void);
* @delay_frames : Amount of delay frames.
* @check_frames : Frequency with which to check CRCs.
* @cb : Libretro callbacks.
* @spectate : If true, enable spectator mode.
* @nat_traversal : If true, attempt NAT traversal.
* @nick : Nickname of user.
* @quirks : Netplay quirks.
@ -412,7 +401,7 @@ void input_poll_net(void);
**/
netplay_t *netplay_new(void *direct_host, const char *server,
uint16_t port, unsigned delay_frames, unsigned check_frames,
const struct retro_callbacks *cb, bool spectate, bool nat_traversal,
const struct retro_callbacks *cb, bool nat_traversal,
const char *nick, uint64_t quirks);
/**
@ -476,8 +465,6 @@ bool netplay_disconnect(netplay_t *netplay);
struct netplay_callbacks* netplay_get_cbs_net(void);
struct netplay_callbacks* netplay_get_cbs_spectate(void);
/* Normally called at init time, unless the INITIALIZATION quirk is set */
bool netplay_init_serialization(netplay_t *netplay);
@ -503,8 +490,6 @@ uint32_t netplay_impl_magic(void);
bool netplay_is_server(netplay_t* netplay);
bool netplay_is_spectate(netplay_t* netplay);
bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta, uint32_t frame);
uint32_t netplay_delta_frame_crc(netplay_t *netplay, struct delta_frame *delta);

View File

@ -1,305 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2016 - Gregor Richards
*
* 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 <compat/strl.h>
#include <stdio.h>
#include <net/net_compat.h>
#include <net/net_socket.h>
#include <retro_endianness.h>
#include "netplay_private.h"
#include "retro_assert.h"
#include "../../autosave.h"
/**
* netplay_spectate_pre_frame:
* @netplay : pointer to netplay object
*
* Pre-frame for Netplay (spectator version).
**/
static bool netplay_spectate_pre_frame(netplay_t *netplay)
{
if (netplay_is_server(netplay))
{
fd_set fds;
int new_fd, idx, i;
struct sockaddr_storage their_addr;
socklen_t addr_size;
retro_ctx_serialize_info_t serial_info;
uint32_t header[3];
struct timeval tmp_tv = {0};
netplay->can_poll = true;
input_poll_net();
/* Send our input to any connected spectators */
for (i = 0; i < MAX_SPECTATORS; i++)
{
if (netplay->spectate.fds[i] >= 0)
{
netplay->input_packet_buffer[2] = htonl(netplay->self_frame_count - netplay->spectate.frames[i]);
if (!socket_send_all_blocking(netplay->spectate.fds[i], netplay->input_packet_buffer, sizeof(netplay->input_packet_buffer), false))
{
socket_close(netplay->spectate.fds[i]);
netplay->spectate.fds[i] = -1;
}
}
}
/* Check for connections */
FD_ZERO(&fds);
FD_SET(netplay->listen_fd, &fds);
if (socket_select(netplay->listen_fd + 1, &fds, NULL, NULL, &tmp_tv) <= 0)
return true;
if (!FD_ISSET(netplay->listen_fd, &fds))
return true;
addr_size = sizeof(their_addr);
new_fd = accept(netplay->listen_fd, (struct sockaddr*)&their_addr, &addr_size);
if (new_fd < 0)
{
RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR));
return true;
}
idx = -1;
for (i = 0; i < MAX_SPECTATORS; i++)
{
if (netplay->spectate.fds[i] == -1)
{
idx = i;
break;
}
}
/* No vacant client streams :( */
if (idx == -1)
{
socket_close(new_fd);
return true;
}
#if 0
if (!netplay_get_nickname(netplay, new_fd))
{
RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT));
socket_close(new_fd);
return true;
}
if (!netplay_send_nickname(netplay, new_fd))
{
RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT));
socket_close(new_fd);
return true;
}
#endif
/* Wait until it's safe to serialize */
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
{
netplay->is_replay = true;
netplay->replay_ptr = netplay->self_ptr;
netplay->replay_frame_count = netplay->self_frame_count;
netplay_wait_and_init_serialization(netplay);
netplay->is_replay = false;
}
/* Start them at the current frame */
netplay->spectate.frames[idx] = netplay->self_frame_count;
serial_info.data_const = NULL;
serial_info.data = netplay->buffer[netplay->self_ptr].state;
serial_info.size = netplay->state_size;
if (core_serialize(&serial_info))
{
/* Send them the savestate */
header[0] = htonl(NETPLAY_CMD_LOAD_SAVESTATE);
header[1] = htonl(serial_info.size + sizeof(uint32_t));
header[2] = htonl(0);
if (!socket_send_all_blocking(new_fd, header, sizeof(header), false))
{
socket_close(new_fd);
return true;
}
if (!socket_send_all_blocking(new_fd, serial_info.data, serial_info.size, false))
{
socket_close(new_fd);
return true;
}
}
/* And send them this frame's input */
netplay->input_packet_buffer[2] = htonl(0);
if (!socket_send_all_blocking(new_fd, netplay->input_packet_buffer, sizeof(netplay->input_packet_buffer), false))
{
socket_close(new_fd);
return true;
}
netplay->spectate.fds[idx] = new_fd;
}
else
{
if (netplay_delta_frame_ready(netplay, &netplay->buffer[netplay->self_ptr], netplay->self_frame_count))
{
/* Mark our own data as already read, so we ignore local input */
netplay->buffer[netplay->self_ptr].have_local = true;
}
netplay->can_poll = true;
input_poll_net();
/* Only proceed if we have data */
if (netplay->read_frame_count <= netplay->self_frame_count)
return false;
}
return true;
}
/**
* netplay_spectate_post_frame:
* @netplay : pointer to netplay object
*
* Post-frame for Netplay (spectator version).
* Not much here, just fast forward if we're behind the server.
**/
static void netplay_spectate_post_frame(netplay_t *netplay)
{
netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
netplay->self_frame_count++;
if (netplay_is_server(netplay))
{
/* Not expecting any client data */
netplay->read_ptr = netplay->other_ptr = netplay->self_ptr;
netplay->read_frame_count = netplay->other_frame_count = netplay->self_frame_count;
}
else
{
/* If we must rewind, it's because we got a save state */
if (netplay->force_rewind)
{
retro_ctx_serialize_info_t serial_info;
/* Replay frames. */
netplay->is_replay = true;
netplay->replay_ptr = netplay->other_ptr;
netplay->replay_frame_count = netplay->other_frame_count;
/* Wait until it's safe to serialize */
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
netplay_wait_and_init_serialization(netplay);
serial_info.data = NULL;
serial_info.data_const = netplay->buffer[netplay->replay_ptr].state;
serial_info.size = netplay->state_size;
core_unserialize(&serial_info);
while (netplay->replay_frame_count < netplay->self_frame_count)
{
autosave_lock();
core_run();
autosave_unlock();
netplay->replay_ptr = NEXT_PTR(netplay->replay_ptr);
netplay->replay_frame_count++;
}
netplay->is_replay = false;
netplay->force_rewind = false;
}
/* We're in sync by definition */
if (netplay->read_frame_count < netplay->self_frame_count)
{
netplay->other_ptr = netplay->read_ptr;
netplay->other_frame_count = netplay->read_frame_count;
}
else
{
netplay->other_ptr = netplay->self_ptr;
netplay->other_frame_count = netplay->self_frame_count;
}
/* If the server gets significantly ahead, skip to catch up */
if (netplay->self_frame_count + netplay->delay_frames <= netplay->read_frame_count)
{
/* "Replay" into the future */
netplay->is_replay = true;
netplay->replay_ptr = netplay->self_ptr;
netplay->replay_frame_count = netplay->self_frame_count;
while (netplay->replay_frame_count < netplay->read_frame_count - 1)
{
autosave_lock();
core_run();
autosave_unlock();
netplay->replay_ptr = NEXT_PTR(netplay->replay_ptr);
netplay->replay_frame_count++;
netplay->self_ptr = netplay->replay_ptr;
netplay->self_frame_count = netplay->replay_frame_count;
}
netplay->is_replay = false;
}
}
}
static bool netplay_spectate_info_cb(netplay_t* netplay, unsigned frames)
{
if (netplay_is_server(netplay))
{
int i;
for (i = 0; i < MAX_SPECTATORS; i++)
netplay->spectate.fds[i] = -1;
}
else
{
#if 0
if (!netplay_send_nickname(netplay, netplay->connections[0].fd))
return false;
if (!netplay_get_nickname(netplay, netplay->connections[0].fd))
return false;
#endif
}
netplay->connections[0].mode = netplay->self_mode = NETPLAY_CONNECTION_PLAYING;
return true;
}
struct netplay_callbacks* netplay_get_cbs_spectate(void)
{
static struct netplay_callbacks cbs = {
&netplay_spectate_pre_frame,
&netplay_spectate_post_frame,
&netplay_spectate_info_cb
};
return &cbs;
}

View File

@ -342,7 +342,6 @@ static void retroarch_print_help(const char *arg0)
puts(" -F, --frames=NUMBER Delay frames when using netplay.");
puts(" --check-frames=NUMBER\n"
" Check frames when using netplay.");
puts(" --spectate Connect to netplay server as spectator.");
#if defined(HAVE_NETWORK_CMD)
puts(" --command Sends a command over UDP to an already "
"running program process.");
@ -430,7 +429,6 @@ static void retroarch_parse_input(int argc, char *argv[])
{ "frames", 1, NULL, 'F' },
{ "check-frames", 1, NULL, RA_OPT_CHECK_FRAMES },
{ "port", 1, NULL, RA_OPT_PORT },
{ "spectate", 0, NULL, RA_OPT_SPECTATE },
#if defined(HAVE_NETWORK_CMD)
{ "command", 1, NULL, RA_OPT_COMMAND },
#endif
@ -725,12 +723,6 @@ static void retroarch_parse_input(int argc, char *argv[])
settings->netplay.port = strtoul(optarg, NULL, 0);
break;
case RA_OPT_SPECTATE:
retroarch_override_setting_set(
RARCH_OVERRIDE_SETTING_NETPLAY_MODE, NULL);
settings->netplay.is_spectate = true;
break;
#if defined(HAVE_NETWORK_CMD)
case RA_OPT_COMMAND:
if (command_network_send((const char*)optarg))