diff options
-rw-r--r-- | src/d_loop.c | 28 | ||||
-rw-r--r-- | src/net_client.c | 52 | ||||
-rw-r--r-- | src/net_client.h | 3 | ||||
-rw-r--r-- | src/net_defs.h | 3 | ||||
-rw-r--r-- | src/net_gui.c | 20 | ||||
-rw-r--r-- | src/net_gui.h | 6 | ||||
-rw-r--r-- | src/net_server.c | 76 |
7 files changed, 141 insertions, 47 deletions
diff --git a/src/d_loop.c b/src/d_loop.c index 0206e85a..618c7240 100644 --- a/src/d_loop.c +++ b/src/d_loop.c @@ -309,6 +309,24 @@ void D_StartGameLoop(void) lasttime = GetAdjustedTime() / ticdup; } +// +// Block until the game start message is received from the server. +// + +void D_BlockUntilStart(net_gamesettings_t *settings) +{ + while (!NET_CL_GetSettings(settings)) + { + NET_CL_Run(); + NET_SV_Run(); + + if (!net_client_connected) + { + I_Error("Lost connection to server"); + } + } +} + boolean D_InitNetGame(net_connect_data_t *connect_data, net_gamesettings_t *settings) { @@ -440,9 +458,15 @@ boolean D_InitNetGame(net_connect_data_t *connect_data, printf("D_CheckNetGame: Connected to %s\n", NET_AddrToString(addr)); - // Wait for game start message received from server. + // Wait for launch message received from server. + + NET_WaitForLaunch(); + + // Send our game settings and block until game start is received + // from the server. - NET_WaitForStart(settings); + NET_CL_StartGame(settings); + D_BlockUntilStart(settings); // Read the game settings that were received. diff --git a/src/net_client.c b/src/net_client.c index 43e28441..f258eb44 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -51,6 +51,10 @@ extern void D_ReceiveTic(ticcmd_t *ticcmds, boolean *playeringame); typedef enum { + // waiting for the game to launch + + CLIENT_STATE_WAITING_LAUNCH, + // waiting for the game to start CLIENT_STATE_WAITING_START, @@ -73,10 +77,10 @@ typedef struct unsigned int resend_time; - // Tic data from server + // Tic data from server net_full_ticcmd_t cmd; - + } net_server_recv_t; // Type of structure used in the send window @@ -115,15 +119,15 @@ static net_gamesettings_t settings; boolean net_client_connected; -// true if we have received waiting data from the server +// true if we have received waiting data from the server, +// and the wait data that was received. boolean net_client_received_wait_data; - net_waitdata_t net_client_wait_data; -// Waiting for the game to start? +// Waiting at the initial wait screen for the game to be launched? -boolean net_waiting_for_start = false; +boolean net_waiting_for_launch = false; // Name that we send to the server @@ -306,6 +310,11 @@ static void NET_CL_Shutdown(void) } } +void NET_CL_LaunchGame(void) +{ + NET_Conn_NewReliable(&client_connection, NET_PACKET_TYPE_LAUNCH); +} + void NET_CL_StartGame(net_gamesettings_t *settings) { net_packet_t *packet; @@ -457,6 +466,16 @@ static void NET_CL_ParseWaitingData(net_packet_t *packet) net_client_received_wait_data = true; } +static void NET_CL_ParseLaunch(net_packet_t *packet) +{ + if (client_state != CLIENT_STATE_WAITING_LAUNCH) + { + return; + } + + client_state = CLIENT_STATE_WAITING_START; +} + static void NET_CL_ParseGameStart(net_packet_t *packet) { if (!NET_ReadSettings(packet, &settings)) @@ -805,6 +824,10 @@ static void NET_CL_ParsePacket(net_packet_t *packet) NET_CL_ParseWaitingData(packet); break; + case NET_PACKET_TYPE_LAUNCH: + NET_CL_ParseLaunch(packet); + break; + case NET_PACKET_TYPE_GAMESTART: NET_CL_ParseGameStart(packet); break; @@ -864,12 +887,13 @@ void NET_CL_Run(void) || client_connection.state == NET_CONN_STATE_DISCONNECTED_SLEEP) { NET_CL_Disconnected(); - + NET_CL_Shutdown(); } - - net_waiting_for_start = client_connection.state == NET_CONN_STATE_CONNECTED - && client_state == CLIENT_STATE_WAITING_START; + + net_waiting_for_launch = + client_connection.state == NET_CONN_STATE_CONNECTED + && client_state == CLIENT_STATE_WAITING_LAUNCH; if (client_state == CLIENT_STATE_IN_GAME) { @@ -932,7 +956,7 @@ boolean NET_CL_Connect(net_addr_t *addr, net_connect_data_t *data) NET_Conn_InitClient(&client_connection, addr); // try to connect - + start_time = I_GetTimeMS(); last_send_time = -1; @@ -947,8 +971,8 @@ boolean NET_CL_Connect(net_addr_t *addr, net_connect_data_t *data) NET_CL_SendSYN(data); last_send_time = nowtime; } - - // time out after 5 seconds + + // time out after 5 seconds if (nowtime - start_time > 5000) { @@ -973,7 +997,7 @@ boolean NET_CL_Connect(net_addr_t *addr, net_connect_data_t *data) { // connected ok! - client_state = CLIENT_STATE_WAITING_START; + client_state = CLIENT_STATE_WAITING_LAUNCH; drone = data->drone; return true; diff --git a/src/net_client.h b/src/net_client.h index 3914849d..9d02d130 100644 --- a/src/net_client.h +++ b/src/net_client.h @@ -33,6 +33,7 @@ boolean NET_CL_Connect(net_addr_t *addr, net_connect_data_t *data); void NET_CL_Disconnect(void); void NET_CL_Run(void); void NET_CL_Init(void); +void NET_CL_LaunchGame(void); void NET_CL_StartGame(net_gamesettings_t *settings); void NET_CL_SendTiccmd(ticcmd_t *ticcmd, int maketic); boolean NET_CL_GetSettings(net_gamesettings_t *_settings); @@ -43,7 +44,7 @@ void NET_BindVariables(void); extern boolean net_client_connected; extern boolean net_client_received_wait_data; extern net_waitdata_t net_client_wait_data; -extern boolean net_waiting_for_start; +extern boolean net_waiting_for_launch; extern char *net_player_name; extern sha1_digest_t net_server_wad_sha1sum; diff --git a/src/net_defs.h b/src/net_defs.h index ba50f48e..a5804e53 100644 --- a/src/net_defs.h +++ b/src/net_defs.h @@ -116,7 +116,7 @@ struct _net_addr_s // packet types -typedef enum +typedef enum { NET_PACKET_TYPE_SYN, NET_PACKET_TYPE_ACK, @@ -133,6 +133,7 @@ typedef enum NET_PACKET_TYPE_CONSOLE_MESSAGE, NET_PACKET_TYPE_QUERY, NET_PACKET_TYPE_QUERY_RESPONSE, + NET_PACKET_TYPE_LAUNCH, } net_packet_type_t; typedef enum diff --git a/src/net_gui.c b/src/net_gui.c index 14d0d943..d8c584b7 100644 --- a/src/net_gui.c +++ b/src/net_gui.c @@ -54,11 +54,9 @@ static void EscapePressed(TXT_UNCAST_ARG(widget), void *unused) I_Quit(); } -static void StartGame(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(settings)) +static void StartGame(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused)) { - TXT_CAST_ARG(net_gamesettings_t, settings); - - NET_CL_StartGame(settings); + NET_CL_LaunchGame(); } static void OpenWaitDialog(void) @@ -112,7 +110,7 @@ static void BuildWindow(void) TXT_AddWidget(window, drone_label); } -static void UpdateGUI(net_gamesettings_t *settings) +static void UpdateGUI(void) { txt_window_action_t *startgame; char buf[50]; @@ -174,7 +172,7 @@ static void UpdateGUI(net_gamesettings_t *settings) if (net_client_wait_data.is_controller) { startgame = TXT_NewWindowAction(' ', "Start game"); - TXT_SignalConnect(startgame, "pressed", StartGame, settings); + TXT_SignalConnect(startgame, "pressed", StartGame, NULL); } else { @@ -287,11 +285,11 @@ static void CheckSHA1Sums(void) TXT_AddWidget(window, TXT_NewLabel ("If you continue, this may cause your game to desync.")); - + had_warning = true; } -void NET_WaitForStart(net_gamesettings_t *settings) +void NET_WaitForLaunch(void) { if (!TXT_Init()) { @@ -305,9 +303,9 @@ void NET_WaitForStart(net_gamesettings_t *settings) OpenWaitDialog(); had_warning = false; - while (net_waiting_for_start) + while (net_waiting_for_launch) { - UpdateGUI(settings); + UpdateGUI(); CheckSHA1Sums(); TXT_DispatchEvents(); @@ -323,6 +321,6 @@ void NET_WaitForStart(net_gamesettings_t *settings) TXT_Sleep(100); } - + TXT_Shutdown(); } diff --git a/src/net_gui.h b/src/net_gui.h index 9d40b0d0..56f434ec 100644 --- a/src/net_gui.h +++ b/src/net_gui.h @@ -22,15 +22,15 @@ // // * The client waiting screen when we are waiting for the server to // start the game. -// +// -#ifndef NET_GUI_H +#ifndef NET_GUI_H #define NET_GUI_H #include "doomtype.h" -extern void NET_WaitForStart(net_gamesettings_t *settings); +extern void NET_WaitForLaunch(void); #endif /* #ifndef NET_GUI_H */ diff --git a/src/net_server.c b/src/net_server.c index 585f0eac..67f49236 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -56,7 +56,13 @@ typedef enum { - // waiting for the game to start + // waiting for the game to be "launched" (key player to press the start + // button) + + SERVER_WAITING_LAUNCH, + + // game has been launched, we are waiting for all players to be ready + // so the game can start. SERVER_WAITING_START, @@ -65,7 +71,7 @@ typedef enum SERVER_IN_GAME, } net_server_state_t; -typedef struct +typedef struct { boolean active; int player_number; @@ -80,7 +86,7 @@ typedef struct unsigned int connect_time; // Last time new gamedata was received from this client - + int last_gamedata_time; // recording a demo without -longtics @@ -542,7 +548,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet, // will simply not function at all. // - if (M_CheckParm("-ignoreversion") == 0) + if (M_CheckParm("-ignoreversion") == 0) { NET_SV_SendReject(addr, "Version mismatch: server version is: " @@ -578,17 +584,17 @@ static void NET_SV_ParseSYN(net_packet_t *packet, { return; } - + // received a valid SYN // not accepting new connections? - - if (server_state != SERVER_WAITING_START) + + if (server_state != SERVER_WAITING_LAUNCH) { NET_SV_SendReject(addr, "Server is not currently accepting connections"); return; } - + // allocate a client slot if there isn't one already if (client == NULL) @@ -683,6 +689,43 @@ static void NET_SV_ParseSYN(net_packet_t *packet, } } +// Parse a launch packet. This is sent by the key player when the "start" +// button is pressed, and causes the startup process to continue. + +static void NET_SV_ParseLaunch(net_packet_t *packet, net_client_t *client) +{ + unsigned int i; + + // Only the controller can launch the game. + + if (client != NET_SV_Controller()) + { + return; + } + + // Can only launch when we are in the waiting state. + + if (server_state != SERVER_WAITING_LAUNCH) + { + return; + } + + // Forward launch on to all clients. + + for (i=0; i<MAXNETNODES; ++i) + { + if (!ClientConnected(&clients[i])) + continue; + + NET_Conn_NewReliable(&clients[i].connection, + NET_PACKET_TYPE_LAUNCH); + } + + // Now in launch state. + + server_state = SERVER_WAITING_START; +} + // Parse a game start packet static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client) @@ -691,7 +734,7 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client) net_packet_t *startpacket; int nowtime; int i; - + if (client != NET_SV_Controller()) { // Only the controller can start a new game @@ -713,10 +756,10 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client) return; } + // Can only start a game if we are in the waiting start state. + if (server_state != SERVER_WAITING_START) { - // Can only start a game if we are in the waiting start state. - return; } @@ -1232,7 +1275,7 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr) // Packet was eaten by the common connection code } else - { + { //printf("SV: %s: %i\n", NET_AddrToString(addr), packet_type); switch (packet_type) @@ -1240,6 +1283,9 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr) case NET_PACKET_TYPE_GAMESTART: NET_SV_ParseGameStart(packet, client); break; + case NET_PACKET_TYPE_LAUNCH: + NET_SV_ParseLaunch(packet, client); + break; case NET_PACKET_TYPE_GAMEDATA: NET_SV_ParseGameData(packet, client); break; @@ -1502,7 +1548,7 @@ static void NET_SV_GameEnded(void) { int i; - server_state = SERVER_WAITING_START; + server_state = SERVER_WAITING_LAUNCH; sv_gamemode = indetermined; for (i=0; i<MAXNETNODES; ++i) @@ -1557,7 +1603,7 @@ static void NET_SV_RunClient(net_client_t *client) return; } - if (server_state == SERVER_WAITING_START) + if (server_state == SERVER_WAITING_LAUNCH) { // Waiting for the game to start @@ -1605,7 +1651,7 @@ void NET_SV_Init(void) NET_SV_AssignPlayers(); - server_state = SERVER_WAITING_START; + server_state = SERVER_WAITING_LAUNCH; sv_gamemode = indetermined; server_initialized = true; } |