mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 13:20:30 +00:00
Updates to the netplay netpacket interface (#15887)
* Updates to the netplay netpacket interface - Switch environment call number from 76 to 78 (retire 76 as it was never used by any core) - Simplify broadcasts by removing the option to send to all but one client - Separate explicit flushing and querying of incoming packet into two operations (RETRO_NETPACKET_FLUSH_HINT and retro_netpacket_poll_receive_t) - Enable a core to specify a protocol version string which can get used instead of core version to determine compatibility between two players - Log and notify a separate message when there is a content crc mismsatch to convey it being less severe (as different games may be able to do network communication with each other) * C89 compile fix
This commit is contained in:
parent
c976fbb868
commit
107283edc8
@ -13760,6 +13760,10 @@ MSG_HASH(
|
||||
MSG_CONTENT_CRC32S_DIFFER,
|
||||
"Content CRC32s differ. Cannot use different games."
|
||||
)
|
||||
MSG_HASH(
|
||||
MSG_CONTENT_NETPACKET_CRC32S_DIFFER,
|
||||
"Host is running a different game."
|
||||
)
|
||||
MSG_HASH(
|
||||
MSG_PING_TOO_HIGH,
|
||||
"Your ping is too high for this host."
|
||||
|
@ -1810,7 +1810,26 @@ enum retro_mod
|
||||
* even before the microphone driver is ready.
|
||||
*/
|
||||
|
||||
#define RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE 76
|
||||
/* Environment 76 was an obsolete version of RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE.
|
||||
* It was not used by any known core at the time, and was removed from the API. */
|
||||
|
||||
#define RETRO_ENVIRONMENT_GET_DEVICE_POWER (77 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
/* struct retro_device_power * --
|
||||
* Returns the device's current power state as reported by the frontend.
|
||||
* This is useful for emulating the battery level in handheld consoles,
|
||||
* or for reducing power consumption when on battery power.
|
||||
*
|
||||
* The return value indicates whether the frontend can provide this information,
|
||||
* even if the parameter is NULL.
|
||||
*
|
||||
* If the frontend does not support this functionality,
|
||||
* then the provided argument will remain unchanged.
|
||||
*
|
||||
* Note that this environment call describes the power state for the entire device,
|
||||
* not for individual peripherals like controllers.
|
||||
*/
|
||||
|
||||
#define RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE 78
|
||||
/* const struct retro_netpacket_callback * --
|
||||
* When set, a core gains control over network packets sent and
|
||||
* received during a multiplayer session. This can be used to
|
||||
@ -1834,22 +1853,6 @@ enum retro_mod
|
||||
* input devices does not need to take any action on its own.
|
||||
*/
|
||||
|
||||
#define RETRO_ENVIRONMENT_GET_DEVICE_POWER (77 | RETRO_ENVIRONMENT_EXPERIMENTAL)
|
||||
/* struct retro_device_power * --
|
||||
* Returns the device's current power state as reported by the frontend.
|
||||
* This is useful for emulating the battery level in handheld consoles,
|
||||
* or for reducing power consumption when on battery power.
|
||||
*
|
||||
* The return value indicates whether the frontend can provide this information,
|
||||
* even if the parameter is NULL.
|
||||
*
|
||||
* If the frontend does not support this functionality,
|
||||
* then the provided argument will remain unchanged.
|
||||
*
|
||||
* Note that this environment call describes the power state for the entire device,
|
||||
* not for individual peripherals like controllers.
|
||||
*/
|
||||
|
||||
/* VFS functionality */
|
||||
|
||||
/* File paths:
|
||||
@ -3078,32 +3081,44 @@ struct retro_disk_control_ext_callback
|
||||
|
||||
/* Netpacket flags for retro_netpacket_send_t */
|
||||
#define RETRO_NETPACKET_UNRELIABLE 0 /* Packet to be sent unreliable, depending on network quality it might not arrive. */
|
||||
#define RETRO_NETPACKET_RELIABLE (1 << 0) /* Reliable packets are guaranteed to arrive at the target in the order they were send. */
|
||||
#define RETRO_NETPACKET_RELIABLE (1 << 0) /* Reliable packets are guaranteed to arrive at the target in the order they were sent. */
|
||||
#define RETRO_NETPACKET_UNSEQUENCED (1 << 1) /* Packet will not be sequenced with other packets and may arrive out of order. Cannot be set on reliable packets. */
|
||||
#define RETRO_NETPACKET_FLUSH_HINT (1 << 2) /* Request the packet and any previously buffered ones to be sent immediately */
|
||||
|
||||
/* Used by the core to send a packet to one or more connected players.
|
||||
/* Broadcast client_id for retro_netpacket_send_t */
|
||||
#define RETRO_NETPACKET_BROADCAST 0xFFFF
|
||||
|
||||
/* Used by the core to send a packet to one or all connected players.
|
||||
* A single packet sent via this interface can contain up to 64 KB of data.
|
||||
*
|
||||
* The broadcast flag can be set to true to send to multiple connected clients.
|
||||
* In a broadcast, the client_id argument indicates 1 client NOT to send the
|
||||
* packet to (pass 0xFFFF to send to everyone). Otherwise, the client_id
|
||||
* argument indicates a single client to send the packet to.
|
||||
* The client_id RETRO_NETPACKET_BROADCAST sends the packet as a broadcast to
|
||||
* all connected players. This is supported from the host as well as clients.
|
||||
* Otherwise, the argument indicates the player to send the packet to.
|
||||
*
|
||||
* A frontend must support sending reliable packets (RETRO_NETPACKET_RELIABLE).
|
||||
* Unreliable packets might not be supported by the frontend, but the flags can
|
||||
* still be specified. Reliable transmission will be used instead.
|
||||
*
|
||||
* If this function is called passing NULL for buf, it will instead flush all
|
||||
* previously buffered outgoing packets and instantly read any incoming packets.
|
||||
* During such a call, retro_netpacket_receive_t and retro_netpacket_stop_t can
|
||||
* be called. The core can perform this in a loop to do a blocking read, i.e.,
|
||||
* wait for incoming data, but needs to handle stop getting called and also
|
||||
* give up after a short while to avoid freezing on a connection problem.
|
||||
* Calling this with the flag RETRO_NETPACKET_FLUSH_HINT will send off the
|
||||
* packet and any previously buffered ones immediately and without blocking.
|
||||
* To only flush previously queued packets, buf or len can be passed as NULL/0.
|
||||
*
|
||||
* This function is not guaranteed to be thread-safe and must be called during
|
||||
* retro_run or any of the netpacket callbacks passed with this interface.
|
||||
*/
|
||||
typedef void (RETRO_CALLCONV *retro_netpacket_send_t)(int flags, const void* buf, size_t len, uint16_t client_id, bool broadcast);
|
||||
typedef void (RETRO_CALLCONV *retro_netpacket_send_t)(int flags, const void* buf, size_t len, uint16_t client_id);
|
||||
|
||||
/* Optionally read any incoming packets without waiting for the end of the
|
||||
* frame. While polling, retro_netpacket_receive_t and retro_netpacket_stop_t
|
||||
* can be called. The core can perform this in a loop to do a blocking read,
|
||||
* i.e., wait for incoming data, but needs to handle stop getting called and
|
||||
* also give up after a short while to avoid freezing on a connection problem.
|
||||
* It is a good idea to manually flush outgoing packets before calling this.
|
||||
*
|
||||
* This function is not guaranteed to be thread-safe and must be called during
|
||||
* retro_run or any of the netpacket callbacks passed with this interface.
|
||||
*/
|
||||
typedef void (RETRO_CALLCONV *retro_netpacket_poll_receive_t)();
|
||||
|
||||
/* Called by the frontend to signify that a multiplayer session has started.
|
||||
* If client_id is 0 the local player is the host of the session and at this
|
||||
@ -3112,11 +3127,12 @@ typedef void (RETRO_CALLCONV *retro_netpacket_send_t)(int flags, const void* buf
|
||||
* If client_id is > 0 the local player is a client connected to a host and
|
||||
* at this point is already fully connected to the host.
|
||||
*
|
||||
* The core must store the retro_netpacket_send_t function pointer provided
|
||||
* here and use it whenever it wants to send a packet. This function pointer
|
||||
* remains valid until the frontend calls retro_netpacket_stop_t.
|
||||
* The core must store the function pointer send_fn and use it whenever it
|
||||
* wants to send a packet. Optionally poll_receive_fn can be stored and used
|
||||
* when regular receiving between frames is not enough. These function pointers
|
||||
* remain valid until the frontend calls retro_netpacket_stop_t.
|
||||
*/
|
||||
typedef void (RETRO_CALLCONV *retro_netpacket_start_t)(uint16_t client_id, retro_netpacket_send_t send_fn);
|
||||
typedef void (RETRO_CALLCONV *retro_netpacket_start_t)(uint16_t client_id, retro_netpacket_send_t send_fn, retro_netpacket_poll_receive_t poll_receive_fn);
|
||||
|
||||
/* Called by the frontend when a new packet arrives which has been sent from
|
||||
* another player with retro_netpacket_send_t. The client_id argument indicates
|
||||
@ -3125,8 +3141,8 @@ typedef void (RETRO_CALLCONV *retro_netpacket_start_t)(uint16_t client_id, retro
|
||||
typedef void (RETRO_CALLCONV *retro_netpacket_receive_t)(const void* buf, size_t len, uint16_t client_id);
|
||||
|
||||
/* Called by the frontend when the multiplayer session has ended.
|
||||
* Once this gets called the retro_netpacket_send_t function pointer passed
|
||||
* to retro_netpacket_start_t will not be valid anymore.
|
||||
* Once this gets called the function pointers passed to
|
||||
* retro_netpacket_start_t will not be valid anymore.
|
||||
*/
|
||||
typedef void (RETRO_CALLCONV *retro_netpacket_stop_t)(void);
|
||||
|
||||
@ -3153,6 +3169,10 @@ typedef void (RETRO_CALLCONV *retro_netpacket_disconnected_t)(uint16_t client_id
|
||||
* network packets during a multiplayer session between two or more instances
|
||||
* of a libretro frontend.
|
||||
*
|
||||
* Normally during connection handshake the frontend will compare library_version
|
||||
* used by both parties and show a warning if there is a difference. When the core
|
||||
* supplies protocol_version, the frontend will check against this instead.
|
||||
*
|
||||
* @see RETRO_ENVIRONMENT_SET_NETPACKET_INTERFACE
|
||||
*/
|
||||
struct retro_netpacket_callback
|
||||
@ -3163,6 +3183,7 @@ struct retro_netpacket_callback
|
||||
retro_netpacket_poll_t poll; /* Optional - may be NULL */
|
||||
retro_netpacket_connected_t connected; /* Optional - may be NULL */
|
||||
retro_netpacket_disconnected_t disconnected; /* Optional - may be NULL */
|
||||
const char* protocol_version; /* Optional - if not NULL will be used instead of core version to decide if communication is compatible */
|
||||
};
|
||||
|
||||
enum retro_pixel_format
|
||||
|
@ -369,6 +369,7 @@ enum msg_hash_enums
|
||||
MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER,
|
||||
MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION,
|
||||
MSG_CONTENT_CRC32S_DIFFER,
|
||||
MSG_CONTENT_NETPACKET_CRC32S_DIFFER,
|
||||
MSG_PING_TOO_HIGH,
|
||||
MSG_RECORDING_TERMINATED_DUE_TO_RESIZE,
|
||||
MSG_FAILED_TO_START_RECORDING,
|
||||
|
@ -702,9 +702,10 @@ static uint32_t simple_rand_uint32(unsigned long *simple_rand_next)
|
||||
}
|
||||
|
||||
static void netplay_send_cmd_netpacket(netplay_t *netplay, size_t conn_i,
|
||||
const void* buf, size_t len, uint16_t client_id, bool broadcast);
|
||||
const void* buf, size_t len, uint16_t client_id);
|
||||
static void RETRO_CALLCONV netplay_netpacket_send_cb(int flags,
|
||||
const void* buf, size_t len, uint16_t client_id, bool broadcast);
|
||||
const void* buf, size_t len, uint16_t client_id);
|
||||
static void RETRO_CALLCONV netplay_netpacket_poll_receive_cb();
|
||||
|
||||
/*
|
||||
* netplay_init_socket_buffer
|
||||
@ -1191,6 +1192,16 @@ static bool netplay_handshake_info(netplay_t *netplay,
|
||||
"UNKNOWN", sizeof(info_buf.core_version));
|
||||
}
|
||||
|
||||
/* When using the netpacket interface, the core can override the version
|
||||
* with a custom string so multiple core versions can stay compatible. */
|
||||
if (networking_driver_st.core_netpacket_interface &&
|
||||
networking_driver_st.core_netpacket_interface->protocol_version)
|
||||
{
|
||||
strlcpy(info_buf.core_version,
|
||||
networking_driver_st.core_netpacket_interface->protocol_version,
|
||||
sizeof(info_buf.core_version));
|
||||
}
|
||||
|
||||
info_buf.content_crc = htonl(content_get_crc()); /* Get our content CRC */
|
||||
connection->ping_timer = cpu_features_get_time_usec(); /* Third ping */
|
||||
|
||||
@ -1598,6 +1609,7 @@ static bool netplay_handshake_pre_info(netplay_t *netplay,
|
||||
/* Check the core info */
|
||||
if (system)
|
||||
{
|
||||
const char* my_core_version = system->library_version;
|
||||
STRING_SAFE(info_buf.core_name, sizeof(info_buf.core_name));
|
||||
if (!string_is_equal_case_insensitive(
|
||||
info_buf.core_name, system->library_name))
|
||||
@ -1607,19 +1619,29 @@ static bool netplay_handshake_pre_info(netplay_t *netplay,
|
||||
RARCH_ERR("[Netplay] %s\n", dmsg);
|
||||
if (!netplay->is_server)
|
||||
runloop_msg_queue_push(dmsg, 1, 180, false, NULL,
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* When using the netpacket interface, the core can override the version
|
||||
* with a custom string so multiple core versions can stay compatible. */
|
||||
if (networking_driver_st.core_netpacket_interface &&
|
||||
networking_driver_st.core_netpacket_interface->protocol_version)
|
||||
{
|
||||
my_core_version =
|
||||
networking_driver_st.core_netpacket_interface->protocol_version;
|
||||
}
|
||||
|
||||
STRING_SAFE(info_buf.core_version, sizeof(info_buf.core_version));
|
||||
if (!string_is_equal_case_insensitive(
|
||||
info_buf.core_version, system->library_version))
|
||||
info_buf.core_version, my_core_version))
|
||||
{
|
||||
const char *dmsg = msg_hash_to_str(
|
||||
MSG_NETPLAY_DIFFERENT_CORE_VERSIONS);
|
||||
RARCH_WARN("[Netplay] %s\n", dmsg);
|
||||
if (!netplay->is_server && extra_notifications)
|
||||
runloop_msg_queue_push(dmsg, 1, 180, false, NULL,
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1628,11 +1650,14 @@ static bool netplay_handshake_pre_info(netplay_t *netplay,
|
||||
|
||||
if (content_crc && ntohl(info_buf.content_crc) != content_crc)
|
||||
{
|
||||
const char *dmsg = msg_hash_to_str(MSG_CONTENT_CRC32S_DIFFER);
|
||||
/* Warning of a different severety when using netpacket interface */
|
||||
const char *dmsg = msg_hash_to_str(
|
||||
netplay->modus == NETPLAY_MODUS_CORE_PACKET_INTERFACE ?
|
||||
MSG_CONTENT_NETPACKET_CRC32S_DIFFER : MSG_CONTENT_CRC32S_DIFFER);
|
||||
RARCH_WARN("[Netplay] %s\n", dmsg);
|
||||
if (!netplay->is_server && extra_notifications)
|
||||
runloop_msg_queue_push(dmsg, 1, 180, false, NULL,
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING);
|
||||
}
|
||||
|
||||
/* Now switch to the right mode */
|
||||
@ -1920,8 +1945,9 @@ static bool netplay_handshake_pre_sync(netplay_t *netplay,
|
||||
/* Tell a core that uses the netpacket interface that the client is ready */
|
||||
if (networking_driver_st.core_netpacket_interface &&
|
||||
networking_driver_st.core_netpacket_interface->start)
|
||||
networking_driver_st.core_netpacket_interface->start
|
||||
((uint16_t)netplay->self_client_num, netplay_netpacket_send_cb);
|
||||
networking_driver_st.core_netpacket_interface->start(
|
||||
(uint16_t)netplay->self_client_num,
|
||||
netplay_netpacket_send_cb, netplay_netpacket_poll_receive_cb);
|
||||
|
||||
/* Ask to switch to playing mode if we should */
|
||||
if (!settings->bools.netplay_start_as_spectator)
|
||||
@ -6254,7 +6280,6 @@ static bool netplay_get_cmd(netplay_t *netplay,
|
||||
}
|
||||
|
||||
case NETPLAY_CMD_NETPACKET:
|
||||
case NETPLAY_CMD_NETPACKET_BROADCAST:
|
||||
{
|
||||
uint32_t pkt_client_id;
|
||||
void* buf = netplay->zbuffer;
|
||||
@ -6279,36 +6304,38 @@ static bool netplay_get_cmd(netplay_t *netplay,
|
||||
|
||||
if (!netplay->is_server)
|
||||
{
|
||||
/* packets arriving at a client are always meant for us */
|
||||
/* packets arriving at a client are always meant for us
|
||||
* pkt_client_id contains the original sender of the packet */
|
||||
if (networking_driver_st.core_netpacket_interface->receive)
|
||||
networking_driver_st.core_netpacket_interface->receive
|
||||
(buf, cmd_size, (uint16_t)pkt_client_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool broadcast = (cmd == NETPLAY_CMD_NETPACKET_BROADCAST);
|
||||
bool broadcast = (pkt_client_id == RETRO_NETPACKET_BROADCAST);
|
||||
uint16_t incoming_client_id =
|
||||
(uint16_t)(connection - netplay->connections + 1);
|
||||
|
||||
/* check if this is a packet for the host */
|
||||
if ((broadcast ? pkt_client_id : !pkt_client_id)
|
||||
/* check if this is a packet for the host
|
||||
* pkt_client_id designates the recipient of the packet */
|
||||
if ((broadcast || pkt_client_id == 0)
|
||||
&& networking_driver_st.core_netpacket_interface->receive)
|
||||
networking_driver_st.core_netpacket_interface->receive
|
||||
(buf, cmd_size, incoming_client_id);
|
||||
|
||||
if (broadcast)
|
||||
{
|
||||
/* relay to all but designated client and incoming client */
|
||||
size_t i, skip1 = pkt_client_id, skip2 = incoming_client_id;
|
||||
/* relay to all but incoming client */
|
||||
size_t i, skip = incoming_client_id - 1;
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
if (i+1 != skip1 && i+1 != skip2)
|
||||
if (i != skip)
|
||||
netplay_send_cmd_netpacket(netplay, i,
|
||||
buf, cmd_size, incoming_client_id, false);
|
||||
buf, cmd_size, incoming_client_id);
|
||||
}
|
||||
/* Relay unless target is the host or the incoming client */
|
||||
else if (pkt_client_id && pkt_client_id != incoming_client_id)
|
||||
netplay_send_cmd_netpacket(netplay, pkt_client_id-1,
|
||||
buf, cmd_size, incoming_client_id, false);
|
||||
buf, cmd_size, incoming_client_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -8831,7 +8858,8 @@ bool init_netplay(const char *server, unsigned port, const char *mitm_session)
|
||||
/* Tell a core that uses the netpacket interface that the host is ready */
|
||||
if (netplay->is_server && net_st->core_netpacket_interface &&
|
||||
net_st->core_netpacket_interface->start)
|
||||
net_st->core_netpacket_interface->start(0, netplay_netpacket_send_cb);
|
||||
net_st->core_netpacket_interface->start(0,
|
||||
netplay_netpacket_send_cb, netplay_netpacket_poll_receive_cb);
|
||||
|
||||
return true;
|
||||
|
||||
@ -9428,13 +9456,12 @@ bool netplay_decode_hostname(const char *hostname,
|
||||
* @conn_idx : connection index to send cmd to
|
||||
* @buf : packet data pointer
|
||||
* @len : packet data size
|
||||
* @pkt_client_id : source id if host sending to client, otherwise recipient id or excepted id if broadcast
|
||||
* @broadcast : pass true on client if host should relay this to everyone else
|
||||
* @pkt_client_id : source id if host sending to client, otherwise recipient id or RETRO_NETPACKET_BROADCAST
|
||||
*
|
||||
* Send a netpacket command to a connected peer.
|
||||
*/
|
||||
static void netplay_send_cmd_netpacket(netplay_t *netplay, size_t conn_idx,
|
||||
const void* buf, size_t len, uint16_t pkt_client_id, bool broadcast)
|
||||
const void* buf, size_t len, uint16_t pkt_client_id)
|
||||
{
|
||||
struct netplay_connection *connection;
|
||||
struct socket_buffer *sbuf;
|
||||
@ -9446,8 +9473,7 @@ static void netplay_send_cmd_netpacket(netplay_t *netplay, size_t conn_idx,
|
||||
if (!(connection->flags & NETPLAY_CONN_FLAG_ACTIVE)) return;
|
||||
if (connection->mode != NETPLAY_CONNECTION_PLAYING) return;
|
||||
|
||||
cmdbuf[0] = htonl(broadcast
|
||||
? NETPLAY_CMD_NETPACKET_BROADCAST : NETPLAY_CMD_NETPACKET);
|
||||
cmdbuf[0] = htonl(NETPLAY_CMD_NETPACKET);
|
||||
cmdbuf[1] = htonl(len);
|
||||
cmdbuf[2] = htonl(pkt_client_id);
|
||||
|
||||
@ -9461,40 +9487,48 @@ static void netplay_send_cmd_netpacket(netplay_t *netplay, size_t conn_idx,
|
||||
}
|
||||
|
||||
static void RETRO_CALLCONV netplay_netpacket_send_cb(int flags,
|
||||
const void* buf, size_t len, uint16_t client_id, bool broadcast)
|
||||
const void* buf, size_t len, uint16_t client_id)
|
||||
{
|
||||
net_driver_state_t *net_st = &networking_driver_st;
|
||||
netplay_t *netplay = net_st->data;
|
||||
if (!netplay) return;
|
||||
|
||||
if (buf == NULL)
|
||||
if (buf && len)
|
||||
{
|
||||
/* With NULL this function instead flushes packets and checks incoming */
|
||||
netplay_send_flush_all(netplay, NULL);
|
||||
input_poll_net(netplay);
|
||||
return;
|
||||
if (!netplay->is_server)
|
||||
{
|
||||
/* client always sends packet to host, host will relay it if needed */
|
||||
netplay_send_cmd_netpacket(netplay, 0, buf, len, client_id);
|
||||
}
|
||||
else if (client_id == RETRO_NETPACKET_BROADCAST)
|
||||
{
|
||||
/* send packet to all clients */
|
||||
size_t i;
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
netplay_send_cmd_netpacket(netplay, i, buf, len, 0);
|
||||
}
|
||||
else if (client_id)
|
||||
{
|
||||
/* send packet to specific client */
|
||||
netplay_send_cmd_netpacket(netplay, client_id-1, buf, len, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!netplay->is_server)
|
||||
if (flags & RETRO_NETPACKET_FLUSH_HINT)
|
||||
{
|
||||
/* client always sends packet to host, host will relay it if needed */
|
||||
netplay_send_cmd_netpacket(netplay, 0, buf, len, client_id, broadcast);
|
||||
}
|
||||
else if (broadcast)
|
||||
{
|
||||
/* send packet to all clients (client_id can be set as exception) */
|
||||
size_t i;
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
if (i+1 != client_id)
|
||||
netplay_send_cmd_netpacket(netplay, i, buf, len, 0, false);
|
||||
}
|
||||
else if (client_id)
|
||||
{
|
||||
/* send packet to specific client */
|
||||
netplay_send_cmd_netpacket(netplay, client_id-1, buf, len, 0, false);
|
||||
netplay_send_flush_all(netplay, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void RETRO_CALLCONV netplay_netpacket_poll_receive_cb()
|
||||
{
|
||||
net_driver_state_t *net_st = &networking_driver_st;
|
||||
netplay_t *netplay = net_st->data;
|
||||
if (!netplay) return;
|
||||
|
||||
netplay_poll_net_input(netplay);
|
||||
}
|
||||
|
||||
/* Netplay Widgets */
|
||||
|
||||
#ifdef HAVE_GFX_WIDGETS
|
||||
|
@ -165,9 +165,6 @@ enum netplay_cmd
|
||||
/* Send a network packet from the raw packet core interface */
|
||||
NETPLAY_CMD_NETPACKET = 0x0048,
|
||||
|
||||
/* Used by clients to have the host also forward it to other clients */
|
||||
NETPLAY_CMD_NETPACKET_BROADCAST = 0x0049,
|
||||
|
||||
/* Misc. commands */
|
||||
|
||||
/* Sends multiple config requests over,
|
||||
|
Loading…
x
Reference in New Issue
Block a user