From 3631ff74ff62f2ae1ab66820f509107011ef9762 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Mon, 12 Dec 2016 21:57:14 -0500 Subject: [PATCH] Very, very partial support for the server spectating --- network/netplay/netplay.c | 133 ++++++++++++++++++++++-------- network/netplay/netplay_common.c | 2 +- network/netplay/netplay_private.h | 3 + 3 files changed, 102 insertions(+), 36 deletions(-) diff --git a/network/netplay/netplay.c b/network/netplay/netplay.c index 7ab205090a..e47cf05fcc 100644 --- a/network/netplay/netplay.c +++ b/network/netplay/netplay.c @@ -60,6 +60,10 @@ static bool in_netplay = false; static void announce_nat_traversal(netplay_t *netplay); #endif +static bool netplay_send_raw_cmd(netplay_t *netplay, + struct netplay_connection *connection, uint32_t cmd, const void *data, + size_t size); + static void netplay_send_raw_cmd_all(netplay_t *netplay, struct netplay_connection *except, uint32_t cmd, const void *data, size_t size); @@ -430,30 +434,45 @@ static bool send_cur_input(netplay_t *netplay, struct netplay_connection *connec struct delta_frame *dframe = &netplay->buffer[netplay->self_ptr]; uint32_t player; - for (player = 0; player < MAX_USERS; player++) + if (netplay->is_server) { - if (connection->mode == NETPLAY_CONNECTION_PLAYING && - connection->player == player) - continue; - if ((netplay->connected_players & (1<have_real[player]) + if (connection->mode == NETPLAY_CONNECTION_PLAYING && + connection->player == player) + continue; + if ((netplay->connected_players & (1<self_frame_count, player, - dframe->real_input_state[player])) - return false; + if (dframe->have_real[player]) + { + if (!send_input_frame(netplay, connection, NULL, + netplay->self_frame_count, player, + dframe->real_input_state[player])) + return false; + } } } - else if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING && - netplay->self_player == player) + + /* If we're not playing, send a NOINPUT */ + if (netplay->self_mode != NETPLAY_CONNECTION_PLAYING) { - if (!send_input_frame(netplay, connection, NULL, - netplay->self_frame_count, - (netplay->is_server ? NETPLAY_CMD_INPUT_BIT_SERVER : 0) | player, - dframe->self_state)) + uint32_t payload = htonl(netplay->self_frame_count); + if (!netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_NOINPUT, + &payload, sizeof(payload))) return false; } + + } + + /* Send our own data */ + if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING) + { + if (!send_input_frame(netplay, connection, NULL, + netplay->self_frame_count, + (netplay->is_server ? NETPLAY_CMD_INPUT_BIT_SERVER : 0) | netplay->self_player, + dframe->self_state)) + return false; } if (!netplay_send_flush(&connection->send_packet_buffer, connection->fd, @@ -773,6 +792,25 @@ static bool netplay_get_cmd(netplay_t *netplay, break; } + case NETPLAY_CMD_NOINPUT: + { + uint32_t frame; + + if (netplay->is_server) + return netplay_cmd_nak(netplay, connection); + + RECV(&frame, sizeof(frame)) + return netplay_cmd_nak(netplay, connection); + frame = ntohl(frame); + + if (frame != netplay->server_frame_count) + return netplay_cmd_nak(netplay, connection); + + netplay->server_ptr = NEXT_PTR(netplay->server_ptr); + netplay->server_frame_count++; + break; + } + case NETPLAY_CMD_FLIP_PLAYERS: if (cmd_size != sizeof(uint32_t)) { @@ -2046,29 +2084,54 @@ static void netplay_flip_users(netplay_t *netplay) /* Toggle between play mode and spectate mode */ static void netplay_toggle_play_spectate(netplay_t *netplay) { - uint32_t cmd; - size_t i; - if (netplay->is_server) { - /* FIXME */ - return; - } + /* FIXME: Duplication */ + uint32_t payload[2]; + payload[0] = htonl(netplay->self_frame_count+1); + if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING) + { + /* Mark us as no longer playing */ + payload[1] = htonl(netplay->self_player); + netplay->self_mode = NETPLAY_CONNECTION_SPECTATING; + } + else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING) + { + uint32_t player; - if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING) - { - /* Switch to spectator mode immediately */ - netplay->self_mode = NETPLAY_CONNECTION_SPECTATING; - cmd = NETPLAY_CMD_SPECTATE; - } - else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING) - { - /* Switch only after getting permission */ - cmd = NETPLAY_CMD_PLAY; - } - else return; + /* Take a player number */ + for (player = 0; player < MAX_USERS; player++) + if (!(netplay->connected_players & (1<self_mode = NETPLAY_CONNECTION_PLAYING; + netplay->self_player = player; + } + + netplay_send_raw_cmd_all(netplay, NULL, NETPLAY_CMD_MODE, payload, sizeof(payload)); + + } + else + { + uint32_t cmd; + size_t i; + + if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING) + { + /* Switch to spectator mode immediately */ + netplay->self_mode = NETPLAY_CONNECTION_SPECTATING; + cmd = NETPLAY_CMD_SPECTATE; + } + else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING) + { + /* Switch only after getting permission */ + cmd = NETPLAY_CMD_PLAY; + } + else return; + + netplay_send_raw_cmd_all(netplay, NULL, cmd, NULL, 0); + } } diff --git a/network/netplay/netplay_common.c b/network/netplay/netplay_common.c index ca5c8d7f8b..4af02b24e5 100644 --- a/network/netplay/netplay_common.c +++ b/network/netplay/netplay_common.c @@ -262,7 +262,7 @@ static void netplay_handshake_ready(netplay_t *netplay, struct netplay_connectio if (netplay->is_server) { - netplay_log_connection(&connection->addr, 0, connection->nick); + netplay_log_connection(&connection->addr, connection - netplay->connections, connection->nick); /* Send them the savestate */ if (!(netplay->quirks & (NETPLAY_QUIRK_NO_SAVESTATES|NETPLAY_QUIRK_NO_TRANSMISSION))) diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index c363745f8f..bb8371307d 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -95,6 +95,9 @@ enum netplay_cmd /* Input data */ NETPLAY_CMD_INPUT = 0x0003, + /* Non-input data */ + NETPLAY_CMD_NOINPUT = 0x0004, + /* Initialization commands */ /* Inform the other side of our nick (must be first command) */