mirror of
https://github.com/libretro/RetroArch
synced 2025-04-10 15:45:19 +00:00
(Cthulhu88) New Netplay MITM Part 2
This commit is contained in:
parent
109ab785ee
commit
34c374737c
@ -40,7 +40,6 @@
|
|||||||
#define NETPLAY_HOST_LONGSTR_LEN 256
|
#define NETPLAY_HOST_LONGSTR_LEN 256
|
||||||
|
|
||||||
#define NETPLAY_MITM_MAX_PENDING 8
|
#define NETPLAY_MITM_MAX_PENDING 8
|
||||||
#define NETPLAY_MITM_ID_SIZE 16
|
|
||||||
|
|
||||||
enum rarch_netplay_ctl_state
|
enum rarch_netplay_ctl_state
|
||||||
{
|
{
|
||||||
@ -188,14 +187,22 @@ struct netplay_host_list
|
|||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct mitm_id
|
||||||
|
{
|
||||||
|
uint32_t magic;
|
||||||
|
uint8_t unique[12];
|
||||||
|
} mitm_id_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct netplay_mitm_pending
|
struct netplay_mitm_pending
|
||||||
{
|
{
|
||||||
int *fds;
|
int *fds;
|
||||||
uint8_t *ids[NETPLAY_MITM_MAX_PENDING];
|
mitm_id_t *ids;
|
||||||
retro_time_t *timeouts;
|
retro_time_t *timeouts;
|
||||||
|
|
||||||
int current;
|
mitm_id_t id_buf;
|
||||||
int next;
|
size_t id_recvd;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -223,7 +230,7 @@ typedef struct
|
|||||||
bool in_netplay;
|
bool in_netplay;
|
||||||
bool netplay_client_deferred;
|
bool netplay_client_deferred;
|
||||||
bool is_mitm;
|
bool is_mitm;
|
||||||
uint8_t mitm_id[NETPLAY_MITM_ID_SIZE];
|
mitm_id_t mitm_session_id;
|
||||||
struct netplay_mitm_pending mitm_pending;
|
struct netplay_mitm_pending mitm_pending;
|
||||||
bool has_set_netplay_mode;
|
bool has_set_netplay_mode;
|
||||||
bool has_set_netplay_ip_address;
|
bool has_set_netplay_ip_address;
|
||||||
@ -343,7 +350,6 @@ void deinit_netplay(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* init_netplay
|
* init_netplay
|
||||||
* @direct_host : Host to connect to directly, if applicable (client only)
|
|
||||||
* @server : server address to connect to (client only)
|
* @server : server address to connect to (client only)
|
||||||
* @port : TCP port to host on/connect to
|
* @port : TCP port to host on/connect to
|
||||||
*
|
*
|
||||||
@ -353,7 +359,7 @@ void deinit_netplay(void);
|
|||||||
*
|
*
|
||||||
* Returns: true (1) if successful, otherwise false (0).
|
* Returns: true (1) if successful, otherwise false (0).
|
||||||
**/
|
**/
|
||||||
bool init_netplay(void *direct_host, const char *server, unsigned port);
|
bool init_netplay(const char *server, unsigned port);
|
||||||
|
|
||||||
bool init_netplay_deferred(const char* server, unsigned port);
|
bool init_netplay_deferred(const char* server, unsigned port);
|
||||||
|
|
||||||
|
@ -91,6 +91,10 @@
|
|||||||
#define FULL_MAGIC 0x46554C4C /* FULL */
|
#define FULL_MAGIC 0x46554C4C /* FULL */
|
||||||
#define POKE_MAGIC 0x504F4B45 /* POKE */
|
#define POKE_MAGIC 0x504F4B45 /* POKE */
|
||||||
|
|
||||||
|
/* MITM magics */
|
||||||
|
#define MITM_SESSION_MAGIC 0x52415453 /* RATS */
|
||||||
|
#define MITM_CONNECT_MAGIC 0x52415443 /* RATC */
|
||||||
|
|
||||||
#define MAX_CHAT_SIZE 256
|
#define MAX_CHAT_SIZE 256
|
||||||
#define CHAT_FRAME_TIME 600
|
#define CHAT_FRAME_TIME 600
|
||||||
|
|
||||||
@ -2172,7 +2176,7 @@ bool netplay_send(
|
|||||||
/* Can only be that this is simply too big
|
/* Can only be that this is simply too big
|
||||||
* for our buffer, in which case we just
|
* for our buffer, in which case we just
|
||||||
* need to do a blocking send */
|
* need to do a blocking send */
|
||||||
if (!socket_send_all_blocking(sockfd, buf, len, false))
|
if (!socket_send_all_blocking(sockfd, buf, len, true))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2430,7 +2434,7 @@ static bool netplay_full(netplay_t *netplay, int sockfd)
|
|||||||
This is fine; the header is just a warning
|
This is fine; the header is just a warning
|
||||||
for the client. */
|
for the client. */
|
||||||
socket_send_all_nonblocking(sockfd, header,
|
socket_send_all_nonblocking(sockfd, header,
|
||||||
sizeof(header), false);
|
sizeof(header), true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5801,49 +5805,55 @@ static int init_tcp_connection(const struct addrinfo *res,
|
|||||||
host, port);
|
host, port);
|
||||||
dmsg = msg;
|
dmsg = msg;
|
||||||
}
|
}
|
||||||
#else
|
else
|
||||||
dmsg = "Failed to connect to host.";
|
|
||||||
#endif
|
#endif
|
||||||
|
dmsg = "Failed to connect to host.";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef __NETPLAY_MITM_NEW
|
|
||||||
if (use_mitm)
|
if (use_mitm)
|
||||||
{
|
{
|
||||||
if (!socket_connect(fd, (void*)res, false))
|
if (!socket_connect(fd, (void*)res, false))
|
||||||
{
|
{
|
||||||
|
mitm_id_t new_session = {0};
|
||||||
|
mitm_id_t invalid_session = {0};
|
||||||
net_driver_state_t *net_st = &networking_driver_st;
|
net_driver_state_t *net_st = &networking_driver_st;
|
||||||
|
|
||||||
|
/* To request a new session,
|
||||||
|
we send the magic with the rest of the ID zeroed. */
|
||||||
|
new_session.magic = htonl(MITM_SESSION_MAGIC);
|
||||||
|
|
||||||
/* Relay server should provide us with our session ID. */
|
/* Relay server should provide us with our session ID. */
|
||||||
if (socket_receive_all_blocking(fd, net_st->mitm_id, sizeof(net_st->mitm_id)))
|
if (socket_send_all_blocking(fd,
|
||||||
|
&new_session, sizeof(new_session), true) &&
|
||||||
|
socket_receive_all_blocking(fd,
|
||||||
|
&net_st->mitm_session_id, sizeof(net_st->mitm_session_id)) &&
|
||||||
|
ntohl(net_st->mitm_session_id.magic) == MITM_SESSION_MAGIC &&
|
||||||
|
memcmp(&net_st->mitm_session_id.unique, &invalid_session.unique,
|
||||||
|
sizeof(net_st->mitm_session_id.unique)))
|
||||||
{
|
{
|
||||||
/* Initialize data for handling tunneled client connections. */
|
/* Initialize data for handling tunneled client connections. */
|
||||||
int *fds;
|
int *fds;
|
||||||
uint8_t *ids;
|
mitm_id_t *ids;
|
||||||
retro_time_t *timeouts;
|
retro_time_t *timeouts;
|
||||||
|
|
||||||
fds = malloc(
|
fds = malloc(
|
||||||
NETPLAY_MITM_MAX_PENDING * sizeof(*fds));
|
NETPLAY_MITM_MAX_PENDING * sizeof(*fds));
|
||||||
ids = malloc(
|
ids = malloc(
|
||||||
NETPLAY_MITM_MAX_PENDING * NETPLAY_MITM_ID_SIZE * sizeof(*ids));
|
NETPLAY_MITM_MAX_PENDING * sizeof(*ids));
|
||||||
timeouts = malloc(
|
timeouts = malloc(
|
||||||
NETPLAY_MITM_MAX_PENDING * sizeof(*timeouts));
|
NETPLAY_MITM_MAX_PENDING * sizeof(*timeouts));
|
||||||
|
|
||||||
if (fds && ids && timeouts)
|
if (fds && ids && timeouts)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
|
|
||||||
memset(fds, -1,
|
memset(fds, -1,
|
||||||
NETPLAY_MITM_MAX_PENDING * sizeof(*fds));
|
NETPLAY_MITM_MAX_PENDING * sizeof(*fds));
|
||||||
|
|
||||||
for (i = 0; i < NETPLAY_MITM_MAX_PENDING; i++, ids += NETPLAY_MITM_ID_SIZE)
|
|
||||||
net_st->mitm_pending.ids[i] = ids;
|
|
||||||
|
|
||||||
net_st->mitm_pending.fds = fds;
|
net_st->mitm_pending.fds = fds;
|
||||||
|
net_st->mitm_pending.ids = ids;
|
||||||
net_st->mitm_pending.timeouts = timeouts;
|
net_st->mitm_pending.timeouts = timeouts;
|
||||||
|
|
||||||
net_st->mitm_pending.current = 0;
|
net_st->mitm_pending.id_recvd = 0;
|
||||||
net_st->mitm_pending.next = -1;
|
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
@ -5867,14 +5877,13 @@ static int init_tcp_connection(const struct addrinfo *res,
|
|||||||
host, port);
|
host, port);
|
||||||
dmsg = msg;
|
dmsg = msg;
|
||||||
}
|
}
|
||||||
#else
|
else
|
||||||
dmsg = "Failed to connect to relay server.";
|
|
||||||
#endif
|
#endif
|
||||||
|
dmsg = "Failed to connect to relay server.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#endif
|
|
||||||
#if defined(HAVE_INET6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
|
#if defined(HAVE_INET6) && defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
|
||||||
/* Make sure we accept connections on both IPv6 and IPv4 */
|
/* Make sure we accept connections on both IPv6 and IPv4 */
|
||||||
if (res->ai_family == AF_INET6)
|
if (res->ai_family == AF_INET6)
|
||||||
@ -5882,7 +5891,7 @@ static int init_tcp_connection(const struct addrinfo *res,
|
|||||||
int on = 0;
|
int on = 0;
|
||||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
|
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||||
(const char*)&on, sizeof(on)) < 0)
|
(const char*)&on, sizeof(on)) < 0)
|
||||||
RARCH_WARN("Failed to listen on both IPv6 and IPv4\n");
|
RARCH_WARN("Failed to listen on both IPv6 and IPv4.\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (socket_bind(fd, (void*)res))
|
if (socket_bind(fd, (void*)res))
|
||||||
@ -5896,16 +5905,16 @@ static int init_tcp_connection(const struct addrinfo *res,
|
|||||||
if (!getnameinfo(res->ai_addr, res->ai_addrlen,
|
if (!getnameinfo(res->ai_addr, res->ai_addrlen,
|
||||||
NULL, 0, port, sizeof(port), NI_NUMERICSERV))
|
NULL, 0, port, sizeof(port), NI_NUMERICSERV))
|
||||||
{
|
{
|
||||||
snprintf(msg, sizeof(msg), "Failed to bind port %s.", port);
|
snprintf(msg, sizeof(msg),
|
||||||
|
"Failed to bind port %s.",
|
||||||
|
port);
|
||||||
dmsg = msg;
|
dmsg = msg;
|
||||||
}
|
}
|
||||||
#else
|
else
|
||||||
dmsg = "Failed to bind port.";
|
|
||||||
#endif
|
#endif
|
||||||
|
dmsg = "Failed to bind port.";
|
||||||
}
|
}
|
||||||
#ifdef __NETPLAY_MITM_NEW
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_close(fd);
|
socket_close(fd);
|
||||||
@ -6016,6 +6025,12 @@ try_ipv4:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!socket_nonblock(fd))
|
||||||
|
{
|
||||||
|
socket_close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (server)
|
if (server)
|
||||||
{
|
{
|
||||||
netplay->connections[0].active = true;
|
netplay->connections[0].active = true;
|
||||||
@ -6029,13 +6044,13 @@ try_ipv4:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool init_socket(netplay_t *netplay, void *direct_host,
|
static bool init_socket(netplay_t *netplay,
|
||||||
const char *server, uint16_t port)
|
const char *server, const char *mitm, uint16_t port)
|
||||||
{
|
{
|
||||||
if (!network_init())
|
if (!network_init())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!init_tcp_socket(netplay, server, NULL, port))
|
if (!init_tcp_socket(netplay, server, mitm, port))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (netplay->is_server && netplay->nat_traversal)
|
if (netplay->is_server && netplay->nat_traversal)
|
||||||
@ -6211,8 +6226,8 @@ static bool netplay_init_buffers(netplay_t *netplay)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* netplay_new:
|
* netplay_new:
|
||||||
* @direct_host : Netplay host discovered from scanning.
|
|
||||||
* @server : IP address of server.
|
* @server : IP address of server.
|
||||||
|
* @mitm : IP address of the MITM/tunnel server.
|
||||||
* @port : Port of server.
|
* @port : Port of server.
|
||||||
* @stateless_mode : Shall we use stateless mode?
|
* @stateless_mode : Shall we use stateless mode?
|
||||||
* @check_frames : Frequency with which to check CRCs.
|
* @check_frames : Frequency with which to check CRCs.
|
||||||
@ -6226,21 +6241,21 @@ static bool netplay_init_buffers(netplay_t *netplay)
|
|||||||
*
|
*
|
||||||
* Returns: new netplay data.
|
* Returns: new netplay data.
|
||||||
*/
|
*/
|
||||||
netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
|
netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
|
||||||
bool stateless_mode, int check_frames,
|
bool stateless_mode, int check_frames,
|
||||||
const struct retro_callbacks *cb, bool nat_traversal, const char *nick,
|
const struct retro_callbacks *cb, bool nat_traversal, const char *nick,
|
||||||
uint64_t quirks)
|
uint64_t quirks)
|
||||||
{
|
{
|
||||||
netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay));
|
netplay_t *netplay = calloc(1, sizeof(*netplay));
|
||||||
if (!netplay)
|
if (!netplay)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
netplay->listen_fd = -1;
|
netplay->listen_fd = -1;
|
||||||
netplay->tcp_port = port;
|
netplay->tcp_port = port;
|
||||||
netplay->cbs = *cb;
|
netplay->cbs = *cb;
|
||||||
netplay->is_server = (direct_host == NULL && server == NULL);
|
netplay->is_server = !server;
|
||||||
netplay->is_connected = false;
|
netplay->is_connected = false;
|
||||||
netplay->nat_traversal = netplay->is_server ? nat_traversal : false;
|
netplay->nat_traversal = (!server && !mitm) ? nat_traversal : false;
|
||||||
netplay->stateless_mode = stateless_mode;
|
netplay->stateless_mode = stateless_mode;
|
||||||
netplay->check_frames = check_frames;
|
netplay->check_frames = check_frames;
|
||||||
netplay->crc_validity_checked = false;
|
netplay->crc_validity_checked = false;
|
||||||
@ -6266,15 +6281,10 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
|
|||||||
? nick : RARCH_DEFAULT_NICK,
|
? nick : RARCH_DEFAULT_NICK,
|
||||||
sizeof(netplay->nick));
|
sizeof(netplay->nick));
|
||||||
|
|
||||||
if (!init_socket(netplay, direct_host, server, port))
|
if (!init_socket(netplay, server, mitm, port) ||
|
||||||
|
!netplay_init_buffers(netplay))
|
||||||
{
|
{
|
||||||
free(netplay);
|
netplay_free(netplay);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!netplay_init_buffers(netplay))
|
|
||||||
{
|
|
||||||
free(netplay);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6304,30 +6314,7 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
|
|||||||
netplay->self_mode = NETPLAY_CONNECTION_INIT;
|
netplay->self_mode = NETPLAY_CONNECTION_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Not really the right place to do this,
|
|
||||||
* socket initialization needs to be fixed in general. */
|
|
||||||
if (netplay->is_server)
|
|
||||||
{
|
|
||||||
if (!socket_nonblock(netplay->listen_fd))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!socket_nonblock(netplay->connections[0].fd))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return netplay;
|
return netplay;
|
||||||
|
|
||||||
error:
|
|
||||||
if (netplay->listen_fd >= 0)
|
|
||||||
socket_close(netplay->listen_fd);
|
|
||||||
|
|
||||||
if (netplay->connections && netplay->connections[0].fd >= 0)
|
|
||||||
socket_close(netplay->connections[0].fd);
|
|
||||||
|
|
||||||
free(netplay);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7313,34 +7300,6 @@ static void netplay_announce_cb(retro_task_t *task,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mitm_ip && mitm_port)
|
|
||||||
{
|
|
||||||
ip_len = (unsigned)strlen(mitm_ip);
|
|
||||||
port_len = (unsigned)strlen(mitm_port);
|
|
||||||
|
|
||||||
/* Enable Netplay client mode */
|
|
||||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
|
|
||||||
{
|
|
||||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
|
||||||
net_st->is_mitm = true;
|
|
||||||
host_room->host_method = NETPLAY_HOST_METHOD_MITM;
|
|
||||||
}
|
|
||||||
|
|
||||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
|
||||||
|
|
||||||
host_string = (char*)calloc(1, ip_len + port_len + 2);
|
|
||||||
|
|
||||||
memcpy(host_string, mitm_ip, ip_len);
|
|
||||||
memcpy(host_string + ip_len, "|", 1);
|
|
||||||
memcpy(host_string + ip_len + 1, mitm_port, port_len);
|
|
||||||
|
|
||||||
/* Enable Netplay */
|
|
||||||
command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED, (void*)host_string);
|
|
||||||
command_event(CMD_EVENT_NETPLAY_INIT, (void*)host_string);
|
|
||||||
|
|
||||||
free(host_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_DISCORD
|
#ifdef HAVE_DISCORD
|
||||||
if (discord_state_get_ptr()->inited)
|
if (discord_state_get_ptr()->inited)
|
||||||
{
|
{
|
||||||
@ -7602,11 +7561,10 @@ void deinit_netplay(void)
|
|||||||
free(net_st->mitm_pending.fds);
|
free(net_st->mitm_pending.fds);
|
||||||
net_st->mitm_pending.fds = NULL;
|
net_st->mitm_pending.fds = NULL;
|
||||||
}
|
}
|
||||||
if (net_st->mitm_pending.ids[0])
|
if (net_st->mitm_pending.ids)
|
||||||
{
|
{
|
||||||
free(net_st->mitm_pending.ids[0]);
|
free(net_st->mitm_pending.ids);
|
||||||
memset(net_st->mitm_pending.ids, 0,
|
net_st->mitm_pending.ids = NULL;
|
||||||
sizeof(net_st->mitm_pending.ids));
|
|
||||||
}
|
}
|
||||||
if (net_st->mitm_pending.timeouts)
|
if (net_st->mitm_pending.timeouts)
|
||||||
{
|
{
|
||||||
@ -7616,17 +7574,16 @@ void deinit_netplay(void)
|
|||||||
core_unset_netplay_callbacks();
|
core_unset_netplay_callbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_netplay(void *direct_host, const char *server, unsigned port)
|
bool init_netplay(const char *server, unsigned port)
|
||||||
{
|
{
|
||||||
struct retro_callbacks cbs = {0};
|
struct retro_callbacks cbs = {0};
|
||||||
uint64_t serialization_quirks = 0;
|
uint64_t serialization_quirks = 0;
|
||||||
uint64_t quirks = 0;
|
uint64_t quirks = 0;
|
||||||
settings_t *settings = config_get_ptr();
|
settings_t *settings = config_get_ptr();
|
||||||
net_driver_state_t *net_st = &networking_driver_st;
|
net_driver_state_t *net_st = &networking_driver_st;
|
||||||
bool _netplay_is_client = net_st->netplay_is_client;
|
const char *mitm = NULL;
|
||||||
bool _netplay_enabled = net_st->netplay_enabled;
|
|
||||||
|
|
||||||
if (!_netplay_enabled)
|
if (!net_st->netplay_enabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
core_set_default_callbacks(&cbs);
|
core_set_default_callbacks(&cbs);
|
||||||
@ -7651,34 +7608,31 @@ bool init_netplay(void *direct_host, const char *server, unsigned port)
|
|||||||
if (serialization_quirks & NETPLAY_QUIRK_MAP_PLATFORM_DEPENDENT)
|
if (serialization_quirks & NETPLAY_QUIRK_MAP_PLATFORM_DEPENDENT)
|
||||||
quirks |= NETPLAY_QUIRK_PLATFORM_DEPENDENT;
|
quirks |= NETPLAY_QUIRK_PLATFORM_DEPENDENT;
|
||||||
|
|
||||||
if (!_netplay_is_client)
|
if (!net_st->netplay_is_client)
|
||||||
{
|
{
|
||||||
|
server = NULL;
|
||||||
|
if (!port)
|
||||||
|
port = RARCH_DEFAULT_PORT;
|
||||||
runloop_msg_queue_push(
|
runloop_msg_queue_push(
|
||||||
msg_hash_to_str(MSG_WAITING_FOR_CLIENT),
|
msg_hash_to_str(MSG_WAITING_FOR_CLIENT),
|
||||||
0, 180, false,
|
0, 180, false,
|
||||||
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
}
|
||||||
if (settings->bools.netplay_public_announce)
|
else
|
||||||
netplay_announce();
|
{
|
||||||
|
if (net_st->netplay_client_deferred)
|
||||||
|
{
|
||||||
|
server = (const char*)net_st->server_address_deferred;
|
||||||
|
port = net_st->server_port_deferred;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
net_st->data = (netplay_t*)netplay_new(
|
net_st->data = netplay_new(
|
||||||
_netplay_is_client
|
server, mitm, port,
|
||||||
? direct_host
|
|
||||||
: NULL,
|
|
||||||
_netplay_is_client
|
|
||||||
? (!net_st->netplay_client_deferred
|
|
||||||
? server
|
|
||||||
: net_st->server_address_deferred)
|
|
||||||
: NULL,
|
|
||||||
_netplay_is_client ? (!net_st->netplay_client_deferred
|
|
||||||
? port
|
|
||||||
: net_st->server_port_deferred)
|
|
||||||
: (port != 0 ? port : RARCH_DEFAULT_PORT),
|
|
||||||
settings->bools.netplay_stateless_mode,
|
settings->bools.netplay_stateless_mode,
|
||||||
settings->ints.netplay_check_frames,
|
settings->ints.netplay_check_frames,
|
||||||
&cbs,
|
&cbs,
|
||||||
settings->bools.netplay_nat_traversal && !settings->bools.netplay_use_mitm_server,
|
settings->bools.netplay_nat_traversal,
|
||||||
#ifdef HAVE_DISCORD
|
#ifdef HAVE_DISCORD
|
||||||
discord_get_own_username()
|
discord_get_own_username()
|
||||||
? discord_get_own_username()
|
? discord_get_own_username()
|
||||||
@ -7687,21 +7641,21 @@ bool init_netplay(void *direct_host, const char *server, unsigned port)
|
|||||||
settings->paths.username,
|
settings->paths.username,
|
||||||
quirks);
|
quirks);
|
||||||
|
|
||||||
if (net_st->data)
|
if (!net_st->data)
|
||||||
{
|
{
|
||||||
if ( net_st->data->is_server
|
RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED));
|
||||||
&& !settings->bools.netplay_start_as_spectator)
|
runloop_msg_queue_push(
|
||||||
netplay_toggle_play_spectate(net_st->data);
|
msg_hash_to_str(MSG_NETPLAY_FAILED),
|
||||||
return true;
|
0, 180, false,
|
||||||
|
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED));
|
if ( net_st->data->is_server
|
||||||
|
&& !settings->bools.netplay_start_as_spectator)
|
||||||
|
netplay_toggle_play_spectate(net_st->data);
|
||||||
|
|
||||||
runloop_msg_queue_push(
|
return true;
|
||||||
msg_hash_to_str(MSG_NETPLAY_FAILED),
|
|
||||||
0, 180, false,
|
|
||||||
NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -760,8 +760,8 @@ bool netplay_wait_and_init_serialization(netplay_t *netplay);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* netplay_new:
|
* netplay_new:
|
||||||
* @direct_host : Netplay host discovered from scanning.
|
|
||||||
* @server : IP address of server.
|
* @server : IP address of server.
|
||||||
|
* @mitm : IP address of the MITM/tunnel server.
|
||||||
* @port : Port of server.
|
* @port : Port of server.
|
||||||
* @stateless_mode : Shall we run in stateless mode?
|
* @stateless_mode : Shall we run in stateless mode?
|
||||||
* @check_frames : Frequency with which to check CRCs.
|
* @check_frames : Frequency with which to check CRCs.
|
||||||
@ -775,8 +775,7 @@ bool netplay_wait_and_init_serialization(netplay_t *netplay);
|
|||||||
*
|
*
|
||||||
* Returns: new netplay data.
|
* Returns: new netplay data.
|
||||||
*/
|
*/
|
||||||
netplay_t *netplay_new(void *direct_host,
|
netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
|
||||||
const char *server, uint16_t port,
|
|
||||||
bool stateless_mode, int check_frames,
|
bool stateless_mode, int check_frames,
|
||||||
const struct retro_callbacks *cb,
|
const struct retro_callbacks *cb,
|
||||||
bool nat_traversal, const char *nick,
|
bool nat_traversal, const char *nick,
|
||||||
|
@ -18,6 +18,6 @@
|
|||||||
#ifndef __RARCH_NETPLAY_PROTOCOL_H
|
#ifndef __RARCH_NETPLAY_PROTOCOL_H
|
||||||
#define __RARCH_NETPLAY_PROTOCOL_H
|
#define __RARCH_NETPLAY_PROTOCOL_H
|
||||||
|
|
||||||
#define NETPLAY_PROTOCOL_VERSION 6
|
#define NETPLAY_PROTOCOL_VERSION 5
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
63
retroarch.c
63
retroarch.c
@ -5239,11 +5239,11 @@ bool command_event(enum event_command cmd, void *data)
|
|||||||
/* init netplay manually */
|
/* init netplay manually */
|
||||||
case CMD_EVENT_NETPLAY_INIT:
|
case CMD_EVENT_NETPLAY_INIT:
|
||||||
{
|
{
|
||||||
char *hostname = (char*)data;
|
bool success;
|
||||||
char *netplay_server = NULL;
|
char *netplay_server = NULL;
|
||||||
unsigned netplay_port = 0;
|
unsigned netplay_port = 0;
|
||||||
|
|
||||||
if (p_rarch->connect_host && !hostname)
|
if (p_rarch->connect_host)
|
||||||
{
|
{
|
||||||
struct string_list *addr_port = string_split(p_rarch->connect_host, "|");
|
struct string_list *addr_port = string_split(p_rarch->connect_host, "|");
|
||||||
|
|
||||||
@ -5281,22 +5281,7 @@ bool command_event(enum event_command cmd, void *data)
|
|||||||
|
|
||||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||||
|
|
||||||
if (!init_netplay(
|
success = init_netplay(netplay_server, netplay_port);
|
||||||
NULL,
|
|
||||||
hostname
|
|
||||||
? hostname
|
|
||||||
: netplay_server, netplay_port))
|
|
||||||
{
|
|
||||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
|
||||||
|
|
||||||
if (p_rarch->connect_host)
|
|
||||||
{
|
|
||||||
free(p_rarch->connect_host);
|
|
||||||
p_rarch->connect_host = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_rarch->connect_host)
|
if (p_rarch->connect_host)
|
||||||
{
|
{
|
||||||
@ -5304,6 +5289,12 @@ bool command_event(enum event_command cmd, void *data)
|
|||||||
p_rarch->connect_host = NULL;
|
p_rarch->connect_host = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable rewind & SRAM autosave if it was enabled
|
/* Disable rewind & SRAM autosave if it was enabled
|
||||||
* TODO/FIXME: Add a setting for these tweaks */
|
* TODO/FIXME: Add a setting for these tweaks */
|
||||||
#ifdef HAVE_REWIND
|
#ifdef HAVE_REWIND
|
||||||
@ -5317,34 +5308,28 @@ bool command_event(enum event_command cmd, void *data)
|
|||||||
/* Initialize netplay via lobby when content is loaded */
|
/* Initialize netplay via lobby when content is loaded */
|
||||||
case CMD_EVENT_NETPLAY_INIT_DIRECT:
|
case CMD_EVENT_NETPLAY_INIT_DIRECT:
|
||||||
{
|
{
|
||||||
/* buf is expected to be address|port */
|
bool success;
|
||||||
static struct string_list *hostname = NULL;
|
/* Expected to be address|port */
|
||||||
char *buf = (char *)data;
|
struct string_list *hostname = string_split((char *)data, "|");
|
||||||
unsigned netplay_port = settings->uints.netplay_port;
|
unsigned netplay_port = !string_is_empty(hostname->elems[1].data) ?
|
||||||
|
strtoul(hostname->elems[1].data, NULL, 10) :
|
||||||
hostname = string_split(buf, "|");
|
settings->uints.netplay_port;
|
||||||
|
|
||||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||||
|
|
||||||
RARCH_LOG("[Netplay]: Connecting to %s:%d (direct)\n",
|
RARCH_LOG("[Netplay]: Connecting to %s:%d (direct)\n",
|
||||||
hostname->elems[0].data, !string_is_empty(hostname->elems[1].data)
|
hostname->elems[0].data, netplay_port);
|
||||||
? atoi(hostname->elems[1].data)
|
|
||||||
: netplay_port);
|
|
||||||
|
|
||||||
if (!init_netplay(
|
success = init_netplay(hostname->elems[0].data, netplay_port);
|
||||||
NULL,
|
|
||||||
hostname->elems[0].data,
|
|
||||||
!string_is_empty(hostname->elems[1].data)
|
|
||||||
? atoi(hostname->elems[1].data)
|
|
||||||
: netplay_port))
|
|
||||||
{
|
|
||||||
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
|
||||||
string_list_free(hostname);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string_list_free(hostname);
|
string_list_free(hostname);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
command_event(CMD_EVENT_NETPLAY_DEINIT, NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable rewind if it was enabled
|
/* Disable rewind if it was enabled
|
||||||
TODO/FIXME: Add a setting for these tweaks */
|
TODO/FIXME: Add a setting for these tweaks */
|
||||||
#ifdef HAVE_REWIND
|
#ifdef HAVE_REWIND
|
||||||
|
Loading…
x
Reference in New Issue
Block a user