1
0
mirror of https://github.com/libretro/RetroArch synced 2024-07-08 12:15:49 +00:00

Netplay and NAT struct improvements (#13416)

Reordered netplay and NAT structs to follow the coding guidelines more closely.

Moved part of the chat struct out of the program's image and into the heap.
This commit is contained in:
Cthulhu-throwaway 2021-12-25 09:42:22 -03:00 committed by GitHub
parent f17deb90c7
commit 26132a2330
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 199 additions and 200 deletions

View File

@ -54,40 +54,40 @@ enum nat_traversal_status
struct natt_device
{
struct sockaddr_in ext_addr;
char desc [512];
char control [512];
char service_type[512];
struct sockaddr_in ext_addr;
bool busy;
};
struct natt_request
{
struct natt_device *device;
struct sockaddr_in addr;
struct natt_device *device;
enum socket_protocol proto;
bool success;
};
struct nat_traversal_data
{
size_t iface;
struct natt_request request;
size_t iface;
enum natt_forward_type forward_type;
enum nat_traversal_status status;
};
typedef struct
{
/* Timeout for our discovery request. */
retro_time_t timeout;
/* List of available network interfaces. */
struct net_ifinfo interfaces;
/* Device we are operating on. */
struct natt_device device;
/* Timeout for our discovery request. */
retro_time_t timeout;
/* File descriptor of the socket we are receiving discovery data. */
int fd;
} natt_state_t;

View File

@ -20,7 +20,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#if !defined(HAVE_SOCKET_LEGACY) && defined(_WIN32)
#if !defined(HAVE_SOCKET_LEGACY) && defined(_WIN32) && defined(_MSC_VER)
#pragma comment(lib, "Iphlpapi")
#endif
@ -43,7 +43,7 @@
#include <iphlpapi.h>
#endif
static natt_state_t natt_st = {{0}, {{0}}, 0, -1};
static natt_state_t natt_st = {0, {0}, {{0}}, -1};
natt_state_t *natt_state_get_ptr(void)
{

View File

@ -200,52 +200,57 @@ struct netplay_host_list
size_t size;
};
struct netplay_chat_data
{
char nick[NETPLAY_NICK_LEN];
char msg[NETPLAY_CHAT_MAX_SIZE];
uint32_t frames;
};
struct netplay_chat_buffer
{
char nick[NETPLAY_NICK_LEN];
char msg[NETPLAY_CHAT_MAX_SIZE];
uint8_t alpha;
};
struct netplay_chat
{
struct
{
struct netplay_chat_data data;
struct netplay_chat_buffer buffer;
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];
} messages[NETPLAY_CHAT_MAX_MESSAGES];
};
typedef struct
{
netplay_t *data; /* Used while Netplay is running */
struct netplay_room host_room; /* ptr alignment */
/* 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
struct netplay_chat_buffer chat_buffer;
struct netplay_room host_room;
struct netplay_room *room_list;
struct netplay_rooms *rooms_data;
/* Used while Netplay is running */
netplay_t *data;
/* Chat messages */
struct netplay_chat *chat;
#ifdef HAVE_NETPLAYDISCOVERY
size_t discovered_hosts_allocated;
/* LAN discovery sockets */
int lan_ad_server_fd;
int lan_ad_client_fd;
/* Packet buffer for advertisement and responses */
struct ad_packet ad_packet_buffer; /* uint32_t alignment */
/* List of discovered hosts */
struct netplay_host_list discovered_hosts;
size_t discovered_hosts_allocated;
#endif
int room_count;
int reannounce;
int reping;
int latest_ping;
uint16_t mapping[RETROK_LAST];
unsigned server_port_deferred;
uint16_t mapping[RETROK_LAST];
char server_address_deferred[256];
char server_session_deferred[32];
bool netplay_client_deferred;
@ -259,10 +264,6 @@ typedef struct
bool has_set_netplay_ip_port;
bool has_set_netplay_stateless_mode;
bool has_set_netplay_check_frames;
/* NAT traversal info (if NAT traversal is used and serving) */
struct nat_traversal_data nat_traversal_request;
/* Chat messages */
struct netplay_chat chat;
} net_driver_state_t;
net_driver_state_t *networking_state_get_ptr(void);

View File

@ -20,7 +20,7 @@
#pragma comment(lib, "ws2_32")
#endif
#ifdef _WIN32
#if defined(_WIN32) && defined(_MSC_VER)
#pragma comment(lib, "Iphlpapi")
#endif
@ -4891,7 +4891,6 @@ static void relay_chat(netplay_t *netplay,
static void show_chat(const char *nick, const char *msg)
{
char formatted_chat[NETPLAY_CHAT_MAX_SIZE];
net_driver_state_t *net_st = &networking_driver_st;
/* Truncate the message if necessary. */
snprintf(formatted_chat, sizeof(formatted_chat),
@ -4902,30 +4901,35 @@ static void show_chat(const char *nick, const char *msg)
#ifdef HAVE_GFX_WIDGETS
if (gfx_widgets_ready())
{
struct netplay_chat_data *data;
uint32_t msg_slot;
net_driver_state_t *net_st = &networking_driver_st;
struct netplay_chat *chat = net_st->chat;
/* Do we have a free slot for this message?
If not, get rid of the oldest message to make room for it. */
if (!net_st->chat.message_slots)
if (!chat->message_slots)
{
int i;
for (i = ARRAY_SIZE(net_st->chat.messages) - 2; i >= 0; i--)
for (i = ARRAY_SIZE(chat->messages) - 2; i >= 0; i--)
{
memcpy(&net_st->chat.messages[i+1].data,
&net_st->chat.messages[i].data,
sizeof(*data));
memcpy(&chat->messages[i+1], &chat->messages[i],
sizeof(*chat->messages));
}
data = &net_st->chat.messages[0].data;
msg_slot = 0;
}
else
{
data = &net_st->chat.messages[--net_st->chat.message_slots].data;
msg_slot = --chat->message_slots;
}
strlcpy(data->nick, nick, sizeof(data->nick));
strlcpy(data->msg, msg, sizeof(data->msg));
data->frames = NETPLAY_CHAT_FRAME_TIME;
chat->messages[msg_slot].frames =
NETPLAY_CHAT_FRAME_TIME;
strlcpy(chat->messages[msg_slot].nick, nick,
sizeof(chat->messages[msg_slot].nick));
strlcpy(chat->messages[msg_slot].msg, msg,
sizeof(chat->messages[msg_slot].msg));
}
else
#endif
@ -8309,12 +8313,8 @@ void deinit_netplay(void)
#endif
}
for (i = 0; i < ARRAY_SIZE(net_st->chat.messages); i++)
{
*net_st->chat.messages[i].data.nick = '\0';
*net_st->chat.messages[i].data.msg = '\0';
net_st->chat.messages[i].data.frames = 0;
}
free(net_st->chat);
net_st->chat = NULL;
core_unset_netplay_callbacks();
}
@ -8432,13 +8432,10 @@ bool init_netplay(const char *server, unsigned port, const char *mitm_session)
return false;
}
for (i = 0; i < ARRAY_SIZE(net_st->chat.messages); i++)
{
*net_st->chat.messages[i].data.nick = '\0';
*net_st->chat.messages[i].data.msg = '\0';
net_st->chat.messages[i].data.frames = 0;
}
net_st->chat.message_slots = ARRAY_SIZE(net_st->chat.messages);
net_st->chat = calloc(1, sizeof(*net_st->chat));
if (!net_st->chat)
return false;
net_st->chat->message_slots = ARRAY_SIZE(net_st->chat->messages);
net_st->reannounce = -1;
net_st->reping = -1;
@ -8680,56 +8677,66 @@ static void gfx_widget_netplay_chat_iterate(void *user_data,
bool is_threaded)
{
size_t i;
settings_t *settings = config_get_ptr();
net_driver_state_t *net_st = &networking_driver_st;
#ifdef HAVE_MENU
bool menu_open = menu_state_get_ptr()->alive;
#endif
bool fade_chat = settings->bools.netplay_fade_chat;
struct netplay_chat *chat = net_st->chat;
struct netplay_chat_buffer *chat_buffer = &net_st->chat_buffer;
/* Move the messages to a thread-safe buffer
before drawing them. */
for (i = 0; i < ARRAY_SIZE(net_st->chat.messages); i++)
if (chat)
{
struct netplay_chat_data *data =
&net_st->chat.messages[i].data;
struct netplay_chat_buffer *buffer =
&net_st->chat.messages[i].buffer;
/* Don't show chat while in the menu */
settings_t *settings = config_get_ptr();
#ifdef HAVE_MENU
if (menu_open)
bool menu_open = menu_state_get_ptr()->alive;
#endif
bool fade_chat = settings->bools.netplay_fade_chat;
/* Move the messages to a thread-safe buffer
before drawing them. */
for (i = 0; i < ARRAY_SIZE(chat->messages); i++)
{
buffer->alpha = 0;
continue;
}
uint32_t *frames = &chat->messages[i].frames;
uint8_t *alpha = &chat_buffer->messages[i].alpha;
#ifdef HAVE_MENU
/* Don't show chat while in the menu */
if (menu_open)
{
*alpha = 0;
continue;
}
#endif
/* If we are not fading, set alpha to max. */
if (!fade_chat)
{
buffer->alpha = 0xFF;
}
else if (data->frames)
{
float alpha_percent = (float) data->frames /
(float) NETPLAY_CHAT_FRAME_TIME;
/* If we are not fading, set alpha to max. */
if (!fade_chat)
{
*alpha = 0xFF;
}
else if (*frames)
{
float alpha_percent = (float) *frames /
(float) NETPLAY_CHAT_FRAME_TIME;
buffer->alpha = (uint8_t) float_max(
alpha_percent * 255.0f, 1.0f);
*alpha = (uint8_t) float_max(
alpha_percent * 255.0f, 1.0f);
data->frames--;
}
else
{
buffer->alpha = 0;
continue;
}
(*frames)--;
}
else
{
*alpha = 0;
continue;
}
memcpy(buffer->nick, data->nick,
sizeof(buffer->nick));
memcpy(buffer->msg, data->msg,
sizeof(buffer->msg));
memcpy(chat_buffer->messages[i].nick, chat->messages[i].nick,
sizeof(chat_buffer->messages[i].nick));
memcpy(chat_buffer->messages[i].msg, chat->messages[i].msg,
sizeof(chat_buffer->messages[i].msg));
}
}
/* If we are not in netplay, do nothing. */
else
{
for (i = 0; i < ARRAY_SIZE(chat->messages); i++)
chat_buffer->messages[i].alpha = 0;
}
}
@ -8739,24 +8746,22 @@ static void gfx_widget_netplay_chat_frame(void *data, void *userdata)
video_frame_info_t *video_info = data;
dispgfx_widget_t *p_dispwidget = userdata;
net_driver_state_t *net_st = &networking_driver_st;
struct netplay_chat_buffer *chat_buffer = &net_st->chat_buffer;
int line_height =
p_dispwidget->gfx_widget_fonts.regular.line_height +
p_dispwidget->simple_widget_padding / 3.0f;
int height =
video_info->height - line_height;
for (i = 0; i < ARRAY_SIZE(net_st->chat.messages); i++)
for (i = 0; i < ARRAY_SIZE(chat_buffer->messages); i++)
{
char formatted_nick[NETPLAY_CHAT_MAX_SIZE];
char formatted_msg[NETPLAY_CHAT_MAX_SIZE];
int formatted_nick_len;
int formatted_nick_width;
const char *nick =
net_st->chat.messages[i].buffer.nick;
const char *msg =
net_st->chat.messages[i].buffer.msg;
uint8_t alpha =
net_st->chat.messages[i].buffer.alpha;
uint8_t alpha = chat_buffer->messages[i].alpha;
const char *nick = chat_buffer->messages[i].nick;
const char *msg = chat_buffer->messages[i].msg;
if (!alpha || string_is_empty(nick) || string_is_empty(msg))
continue;

View File

@ -324,6 +324,10 @@ struct delta_frame
/* The real input */
netplay_input_state_t real_input[MAX_INPUT_DEVICES]; /* ptr alignment */
/* 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];
/* The serialized state of the core at this frame, before input */
void *state;
@ -332,10 +336,6 @@ struct delta_frame
/* The CRC-32 of the serialized state if we've calculated it, else 0 */
uint32_t crc;
/* 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];
/* Have we read local input? */
bool have_local;
@ -362,6 +362,9 @@ struct netplay_connection
/* Is this connection stalling? */
retro_time_t stall_time;
/* Timer used to estimate a connection's latency */
retro_time_t ping_timer;
/* Address of peer */
struct sockaddr_storage addr;
@ -389,6 +392,14 @@ struct netplay_connection
/* 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;
@ -407,17 +418,6 @@ struct netplay_connection
/* Is this connection buffer in use? */
bool active;
/* Which netplay protocol is this connection running? */
uint32_t netplay_protocol;
/* Timer used to estimate a connection's latency */
retro_time_t ping_timer;
/* What latency is this connection running on?
* Network latency has limited precision as we estimate it
* once every pre-frame. */
int32_t ping;
/* Did we request a ping response? */
bool ping_requested;
};
@ -440,19 +440,20 @@ typedef struct mitm_id
#define NETPLAY_MITM_MAX_PENDING 8
struct netplay_mitm_pending
{
int fds[NETPLAY_MITM_MAX_PENDING];
mitm_id_t ids[NETPLAY_MITM_MAX_PENDING];
retro_time_t timeouts[NETPLAY_MITM_MAX_PENDING];
mitm_id_t ids[NETPLAY_MITM_MAX_PENDING];
mitm_id_t id_buf;
size_t id_recvd;
struct addrinfo *base_addr;
struct addrinfo *base_addr;
const struct addrinfo *addr;
size_t id_recvd;
int fds[NETPLAY_MITM_MAX_PENDING];
};
struct netplay
{
/* Quirks in the savestate implementation */
uint64_t quirks;
/* When did we start falling behind? */
retro_time_t catch_up_time;
/* How long have we been stalled? */
@ -466,7 +467,63 @@ struct netplay
retro_time_t frame_run_time[NETPLAY_FRAME_RUN_TIME_WINDOW];
retro_time_t frame_run_time_sum, frame_run_time_avg;
struct netplay_connection one_connection; /* Client only */ /* retro_time_t alignment */
struct retro_callbacks cbs;
/* Compression transcoder */
struct compression_transcoder compress_nil,
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;
/* MITM connection handler */
struct netplay_mitm_pending *mitm_pending;
/* Our local socket info */
struct addrinfo *addr;
struct delta_frame *buffer;
/* A buffer into which to compress frames for transfer */
uint8_t *zbuffer;
size_t connections_size;
size_t buffer_size;
size_t zbuffer_size;
/* The size of our packet buffers */
size_t packet_buffer_size;
/* Size of savestates */
size_t state_size;
/* The frame we're currently inputting */
size_t self_ptr;
/* 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
* 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
* 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
* (as it might not be a player but still synchronizes)
*/
size_t server_ptr;
/* A pointer used temporarily for replay. */
size_t replay_ptr;
/* Pseudo random seed */
unsigned long simple_rand_next;
/* TCP connection for listening (server only) */
int listen_fd;
@ -474,10 +531,6 @@ struct netplay
/* Our client number */
uint32_t self_client_num;
/* All of our connections */
struct netplay_connection *connections;
size_t connections_size;
/* Bitmap of clients with input devices */
uint32_t connected_players;
@ -503,69 +556,19 @@ struct netplay
* as netplay needs fixed devices. */
uint32_t config_devices[MAX_INPUT_DEVICES];
struct retro_callbacks cbs;
struct delta_frame *buffer;
size_t buffer_size;
/* Compression transcoder */
struct compression_transcoder compress_nil,
compress_zlib;
/* Size of savestates */
size_t state_size;
/* A buffer into which to compress frames for transfer */
uint8_t *zbuffer;
size_t zbuffer_size;
/* The size of our packet buffers */
size_t packet_buffer_size;
/* The frame we're currently inputting */
size_t self_ptr;
uint32_t self_frame_count;
/* 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;
uint32_t run_frame_count;
/* The first frame at which some data might be unreliable */
size_t other_ptr;
uint32_t other_frame_count;
/* 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
* is running fast. */
size_t unread_ptr;
uint32_t unread_frame_count;
/* Pointer to the next frame to read from each client */
size_t read_ptr[MAX_CLIENTS];
uint32_t read_frame_count[MAX_CLIENTS];
/* Pointer to the next frame to read from the server
* (as it might not be a player but still synchronizes)
*/
size_t server_ptr;
uint32_t server_frame_count;
/* A pointer used temporarily for replay. */
size_t replay_ptr;
uint32_t replay_frame_count;
/* Our local socket info */
struct addrinfo *addr;
int frame_run_time_ptr;
/* Counter for timeouts */
unsigned timeout_cnt;
int frame_run_time_ptr;
/* Latency frames; positive to hide network latency,
* negative to hide input latency */
int input_latency_frames;
@ -576,6 +579,10 @@ struct netplay
/* How far behind did we fall? */
uint32_t catch_up_behind;
/* Host settings */
int32_t input_latency_frames_min;
int32_t input_latency_frames_max;
/* Are we stalled? */
enum rarch_netplay_stall_reason stall;
@ -616,9 +623,6 @@ struct netplay
/* Force a reset */
bool force_reset;
/* Quirks in the savestate implementation */
uint64_t quirks;
/* Force our state to be sent to all connections */
bool force_send_savestate;
@ -648,19 +652,8 @@ struct netplay
/* Are we the connected? */
bool is_connected;
/* MITM session id */
mitm_id_t mitm_session_id;
/* MITM connection handler */
struct netplay_mitm_pending *mitm_pending;
/* Host settings */
int32_t input_latency_frames_min;
int32_t input_latency_frames_max;
bool allow_pausing;
/* Pseudo random seed */
unsigned long simple_rand_next;
};
/***************************************************************