summaryrefslogtreecommitdiff
path: root/src/net_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/net_server.c')
-rw-r--r--src/net_server.c575
1 files changed, 386 insertions, 189 deletions
diff --git a/src/net_server.c b/src/net_server.c
index 189e824f..a2868370 100644
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -21,14 +21,15 @@
// Network server code
//
+#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
-#include "doomdef.h"
-#include "doomstat.h"
+#include "doomtype.h"
+#include "d_mode.h"
#include "i_system.h"
#include "i_timer.h"
@@ -55,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,
@@ -64,7 +71,7 @@ typedef enum
SERVER_IN_GAME,
} net_server_state_t;
-typedef struct
+typedef struct
{
boolean active;
int player_number;
@@ -73,13 +80,18 @@ typedef struct
int last_send_time;
char *name;
+ // If true, the client has sent the NET_PACKET_TYPE_GAMESTART
+ // message indicating that it is ready for the game to start.
+
+ boolean ready;
+
// Time that this client connected to the server.
// This is used to determine the controller (oldest client).
unsigned int connect_time;
// Last time new gamedata was received from this client
-
+
int last_gamedata_time;
// recording a demo without -longtics
@@ -96,6 +108,10 @@ typedef struct
unsigned int acknowledged;
+ // Value of max_players specified by the client on connect.
+
+ int max_players;
+
// Observer: receives data but does not participate in the game.
boolean drone;
@@ -109,6 +125,10 @@ typedef struct
unsigned int is_freedoom;
+ // Player class (for Hexen)
+
+ int player_class;
+
} net_client_t;
// structure used for the recv window
@@ -135,7 +155,7 @@ typedef struct
static net_server_state_t server_state;
static boolean server_initialized = false;
static net_client_t clients[MAXNETNODES];
-static net_client_t *sv_players[MAXPLAYERS];
+static net_client_t *sv_players[NET_MAXPLAYERS];
static net_context_t *server_context;
static unsigned int sv_gamemode;
static unsigned int sv_gamemission;
@@ -150,7 +170,7 @@ static unsigned int master_resolve_time;
// receive window
static unsigned int recvwindow_start;
-static net_client_recv_t recvwindow[BACKUPTICS][MAXPLAYERS];
+static net_client_recv_t recvwindow[BACKUPTICS][NET_MAXPLAYERS];
#define NET_SV_ExpandTicNum(b) NET_ExpandTicNum(recvwindow_start, (b))
@@ -239,7 +259,7 @@ static void NET_SV_AssignPlayers(void)
}
}
- for (; pl<MAXPLAYERS; ++pl)
+ for (; pl<NET_MAXPLAYERS; ++pl)
{
sv_players[pl] = NULL;
}
@@ -254,7 +274,7 @@ static int NET_SV_NumPlayers(void)
result = 0;
- for (i=0; i<MAXPLAYERS; ++i)
+ for (i=0; i<NET_MAXPLAYERS; ++i)
{
if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
{
@@ -265,6 +285,42 @@ static int NET_SV_NumPlayers(void)
return result;
}
+// Returns the number of players ready to start the game.
+
+static int NET_SV_NumReadyPlayers(void)
+{
+ int result = 0;
+ int i;
+
+ for (i = 0; i < MAXNETNODES; ++i)
+ {
+ if (ClientConnected(&clients[i])
+ && !clients[i].drone && clients[i].ready)
+ {
+ ++result;
+ }
+ }
+
+ return result;
+}
+
+// Returns the maximum number of players that can play.
+
+static int NET_SV_MaxPlayers(void)
+{
+ int i;
+
+ for (i = 0; i < MAXNETNODES; ++i)
+ {
+ if (ClientConnected(&clients[i]))
+ {
+ return clients[i].max_players;
+ }
+ }
+
+ return NET_MAXPLAYERS;
+}
+
// Returns the number of drones currently connected.
static int NET_SV_NumDrones(void)
@@ -305,6 +361,95 @@ static int NET_SV_NumClients(void)
return count;
}
+// returns a pointer to the client which controls the server
+
+static net_client_t *NET_SV_Controller(void)
+{
+ net_client_t *best;
+ int i;
+
+ // Find the oldest client (first to connect).
+
+ best = NULL;
+
+ for (i=0; i<MAXNETNODES; ++i)
+ {
+ // Can't be controller?
+
+ if (!ClientConnected(&clients[i]) || clients[i].drone)
+ {
+ continue;
+ }
+
+ if (best == NULL || clients[i].connect_time < best->connect_time)
+ {
+ best = &clients[i];
+ }
+ }
+
+ return best;
+}
+
+static void NET_SV_SendWaitingData(net_client_t *client)
+{
+ net_waitdata_t wait_data;
+ net_packet_t *packet;
+ net_client_t *controller;
+ int i;
+
+ NET_SV_AssignPlayers();
+
+ controller = NET_SV_Controller();
+
+ wait_data.num_players = NET_SV_NumPlayers();
+ wait_data.num_drones = NET_SV_NumDrones();
+ wait_data.ready_players = NET_SV_NumReadyPlayers();
+ wait_data.max_players = NET_SV_MaxPlayers();
+ wait_data.is_controller = (client == controller);
+ wait_data.consoleplayer = client->player_number;
+
+ // Send the WAD and dehacked checksums of the controlling client.
+ // If no controller found (?), send the details that the client
+ // is expecting anyway.
+
+ if (controller != NULL)
+ {
+ controller = client;
+ }
+
+ memcpy(&wait_data.wad_sha1sum, &controller->wad_sha1sum,
+ sizeof(sha1_digest_t));
+ memcpy(&wait_data.deh_sha1sum, &controller->deh_sha1sum,
+ sizeof(sha1_digest_t));
+ wait_data.is_freedoom = controller->is_freedoom;
+
+ // set name and address of each player:
+
+ for (i = 0; i < wait_data.num_players; ++i)
+ {
+ strncpy(wait_data.player_names[i],
+ sv_players[i]->name,
+ MAXPLAYERNAME);
+ wait_data.player_names[i][MAXPLAYERNAME-1] = '\0';
+
+ strncpy(wait_data.player_addrs[i],
+ NET_AddrToString(sv_players[i]->addr),
+ MAXPLAYERNAME);
+ wait_data.player_addrs[i][MAXPLAYERNAME-1] = '\0';
+ }
+
+ // Construct packet:
+
+ packet = NET_NewPacket(10);
+ NET_WriteInt16(packet, NET_PACKET_TYPE_WAITING_DATA);
+ NET_WriteWaitData(packet, &wait_data);
+
+ // Send packet to client and free
+
+ NET_Conn_SendPacket(&client->connection, packet);
+ NET_FreePacket(packet);
+}
+
// Find the latest tic which has been acknowledged as received by
// all clients.
@@ -354,7 +499,7 @@ static void NET_SV_AdvanceWindow(void)
should_advance = true;
- for (i=0; i<MAXPLAYERS; ++i)
+ for (i=0; i<NET_MAXPLAYERS; ++i)
{
if (sv_players[i] == NULL || !ClientConnected(sv_players[i]))
{
@@ -387,35 +532,6 @@ static void NET_SV_AdvanceWindow(void)
}
}
-// returns a pointer to the client which controls the server
-
-static net_client_t *NET_SV_Controller(void)
-{
- net_client_t *best;
- int i;
-
- // Find the oldest client (first to connect).
-
- best = NULL;
-
- for (i=0; i<MAXNETNODES; ++i)
- {
- // Can't be controller?
-
- if (!ClientConnected(&clients[i]) || clients[i].drone)
- {
- continue;
- }
-
- if (best == NULL || clients[i].connect_time < best->connect_time)
- {
- best = &clients[i];
- }
- }
-
- return best;
-}
-
// Given an address, find the corresponding client
static net_client_t *NET_SV_FindClient(net_addr_t *addr)
@@ -464,6 +580,7 @@ static void NET_SV_InitNewClient(net_client_t *client,
client->sendseq = 0;
client->acknowledged = 0;
client->drone = false;
+ client->ready = false;
client->last_gamedata_time = 0;
@@ -477,11 +594,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet,
net_addr_t *addr)
{
unsigned int magic;
- unsigned int cl_gamemode, cl_gamemission;
- unsigned int cl_recording_lowres;
- unsigned int cl_drone;
- unsigned int is_freedoom;
- sha1_digest_t deh_sha1sum, wad_sha1sum;
+ net_connect_data_t data;
char *player_name;
char *client_version;
int i;
@@ -520,29 +633,30 @@ 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: "
- PACKAGE_STRING);
+ "Different " PACKAGE_NAME " versions cannot play a net game!\n"
+ "Version mismatch: server version is: " PACKAGE_STRING);
return;
}
}
// read the game mode and mission
- if (!NET_ReadInt16(packet, &cl_gamemode)
- || !NET_ReadInt16(packet, &cl_gamemission)
- || !NET_ReadInt8(packet, &cl_recording_lowres)
- || !NET_ReadInt8(packet, &cl_drone)
- || !NET_ReadSHA1Sum(packet, wad_sha1sum)
- || !NET_ReadSHA1Sum(packet, deh_sha1sum)
- || !NET_ReadInt8(packet, &is_freedoom))
+ if (!NET_ReadConnectData(packet, &data))
{
return;
}
- if (!NET_ValidGameMode(cl_gamemode, cl_gamemission))
+ if (!D_ValidGameMode(data.gamemission, data.gamemode))
+ {
+ return;
+ }
+
+ // Check max_players value. This must be in a sensible range.
+
+ if (data.max_players > NET_MAXPLAYERS)
{
return;
}
@@ -555,17 +669,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)
@@ -609,7 +723,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet,
NET_SV_AssignPlayers();
num_players = NET_SV_NumPlayers();
- if ((!cl_drone && num_players >= MAXPLAYERS)
+ if ((!data.drone && num_players >= NET_SV_MaxPlayers())
|| NET_SV_NumClients() >= MAXNETNODES)
{
NET_SV_SendReject(addr, "Server is full!");
@@ -622,33 +736,35 @@ static void NET_SV_ParseSYN(net_packet_t *packet,
// Adopt the game mode and mission of the first connecting client
- if (num_players == 0 && !cl_drone)
+ if (num_players == 0 && !data.drone)
{
- sv_gamemode = cl_gamemode;
- sv_gamemission = cl_gamemission;
+ sv_gamemode = data.gamemode;
+ sv_gamemission = data.gamemission;
}
// Save the SHA1 checksums
- memcpy(client->wad_sha1sum, wad_sha1sum, sizeof(sha1_digest_t));
- memcpy(client->deh_sha1sum, deh_sha1sum, sizeof(sha1_digest_t));
- client->is_freedoom = is_freedoom;
+ memcpy(client->wad_sha1sum, data.wad_sha1sum, sizeof(sha1_digest_t));
+ memcpy(client->deh_sha1sum, data.deh_sha1sum, sizeof(sha1_digest_t));
+ client->is_freedoom = data.is_freedoom;
+ client->max_players = data.max_players;
// Check the connecting client is playing the same game as all
// the other clients
- if (cl_gamemode != sv_gamemode || cl_gamemission != sv_gamemission)
+ if (data.gamemode != sv_gamemode || data.gamemission != sv_gamemission)
{
NET_SV_SendReject(addr, "You are playing the wrong game!");
return;
}
-
+
// Activate, initialize connection
NET_SV_InitNewClient(client, addr, player_name);
- client->recording_lowres = cl_recording_lowres;
- client->drone = cl_drone;
+ client->recording_lowres = data.lowres_turn;
+ client->drone = data.drone;
+ client->player_class = data.player_class;
}
if (client->connection.state == NET_CONN_STATE_WAITING_ACK)
@@ -658,56 +774,88 @@ static void NET_SV_ParseSYN(net_packet_t *packet,
}
}
-// Parse a game start 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_ParseGameStart(net_packet_t *packet, net_client_t *client)
+static void NET_SV_ParseLaunch(net_packet_t *packet, net_client_t *client)
{
- net_gamesettings_t settings;
- net_packet_t *startpacket;
- int nowtime;
- int i;
-
- if (client != NET_SV_Controller())
- {
- // Only the controller can start a new game
+ net_packet_t *launchpacket;
+ int num_players;
+ unsigned int i;
- return;
- }
+ // Only the controller can launch the game.
- if (!NET_ReadSettings(packet, &settings))
+ if (client != NET_SV_Controller())
{
- // Malformed packet
-
return;
}
- // Check the game settings are valid
+ // Can only launch when we are in the waiting state.
- if (!NET_ValidGameSettings(sv_gamemode, sv_gamemission, &settings))
+ if (server_state != SERVER_WAITING_LAUNCH)
{
return;
}
- if (server_state != SERVER_WAITING_START)
+ // Forward launch on to all clients.
+
+ NET_SV_AssignPlayers();
+ num_players = NET_SV_NumPlayers();
+
+ for (i=0; i<MAXNETNODES; ++i)
{
- // Can only start a game if we are in the waiting start state.
+ if (!ClientConnected(&clients[i]))
+ continue;
- return;
+ launchpacket = NET_Conn_NewReliable(&clients[i].connection,
+ NET_PACKET_TYPE_LAUNCH);
+ NET_WriteInt8(launchpacket, num_players);
}
+ // Now in launch state.
+
+ server_state = SERVER_WAITING_START;
+}
+
+// Transition to the in-game state and send all players the start game
+// message. Invoked once all players have indicated they are ready to
+// start the game.
+
+static void StartGame(void)
+{
+ net_packet_t *startpacket;
+ unsigned int i;
+ int nowtime;
+
// Assign player numbers
NET_SV_AssignPlayers();
// Check if anyone is recording a demo and set lowres_turn if so.
- settings.lowres_turn = false;
+ sv_settings.lowres_turn = false;
- for (i=0; i<MAXPLAYERS; ++i)
+ for (i = 0; i < NET_MAXPLAYERS; ++i)
{
if (sv_players[i] != NULL && sv_players[i]->recording_lowres)
{
- settings.lowres_turn = true;
+ sv_settings.lowres_turn = true;
+ }
+ }
+
+ sv_settings.num_players = NET_SV_NumPlayers();
+
+ // Copy player classes:
+
+ for (i = 0; i < NET_MAXPLAYERS; ++i)
+ {
+ if (sv_players[i] != NULL)
+ {
+ sv_settings.player_classes[i] = sv_players[i]->player_class;
+ }
+ else
+ {
+ sv_settings.player_classes[i] = 0;
}
}
@@ -715,7 +863,7 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client)
// Send start packets to each connected node
- for (i=0; i<MAXNETNODES; ++i)
+ for (i = 0; i < MAXNETNODES; ++i)
{
if (!ClientConnected(&clients[i]))
continue;
@@ -725,20 +873,105 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client)
startpacket = NET_Conn_NewReliable(&clients[i].connection,
NET_PACKET_TYPE_GAMESTART);
- NET_WriteInt8(startpacket, NET_SV_NumPlayers());
- NET_WriteInt8(startpacket, clients[i].player_number);
- NET_WriteSettings(startpacket, &settings);
+ sv_settings.consoleplayer = clients[i].player_number;
+
+ NET_WriteSettings(startpacket, &sv_settings);
}
// Change server state
server_state = SERVER_IN_GAME;
- sv_settings = settings;
memset(recvwindow, 0, sizeof(recvwindow));
recvwindow_start = 0;
}
+// Returns true when all nodes have indicated readiness to start the game.
+
+static boolean AllNodesReady(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAXNETNODES; ++i)
+ {
+ if (ClientConnected(&clients[i]) && !clients[i].ready)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Check if the game should start, and if so, start it.
+
+static void CheckStartGame(void)
+{
+ if (AllNodesReady())
+ {
+ StartGame();
+ }
+}
+
+// Send waiting data with current status to all nodes that are ready to
+// start the game.
+
+static void SendAllWaitingData(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAXNETNODES; ++i)
+ {
+ if (ClientConnected(&clients[i]) && clients[i].ready)
+ {
+ NET_SV_SendWaitingData(&clients[i]);
+ }
+ }
+}
+
+// Parse a game start packet
+
+static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client)
+{
+ net_gamesettings_t settings;
+
+ // Can only start a game if we are in the waiting start state.
+
+ if (server_state != SERVER_WAITING_START)
+ {
+ return;
+ }
+
+ if (client == NET_SV_Controller())
+ {
+ if (!NET_ReadSettings(packet, &settings))
+ {
+ // Malformed packet
+
+ return;
+ }
+
+ // Check the game settings are valid
+
+ if (!NET_ValidGameSettings(sv_gamemode, sv_gamemission, &settings))
+ {
+ return;
+ }
+
+ sv_settings = settings;
+ }
+
+ client->ready = true;
+
+ CheckStartGame();
+
+ // Update all ready clients with the current state (number of players
+ // ready, etc.). This is used by games that show startup progress
+ // (eg. Hexen's spinal loading)
+
+ SendAllWaitingData();
+}
+
// Send a resend request to a client
static void NET_SV_SendResendRequest(net_client_t *client, int start, int end)
@@ -1113,7 +1346,7 @@ void NET_SV_SendQueryResponse(net_addr_t *addr)
// Number of players/maximum players
querydata.num_players = NET_SV_NumPlayers();
- querydata.max_players = MAXPLAYERS;
+ querydata.max_players = NET_SV_MaxPlayers();
// Game mode/mission
@@ -1191,7 +1424,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)
@@ -1199,6 +1432,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;
@@ -1225,82 +1461,11 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr)
}
-static void NET_SV_SendWaitingData(net_client_t *client)
-{
- net_packet_t *packet;
- net_client_t *controller;
- int num_players;
- int i;
-
- NET_SV_AssignPlayers();
-
- controller = NET_SV_Controller();
-
- num_players = NET_SV_NumPlayers();
-
- // time to send the client another status packet
-
- packet = NET_NewPacket(10);
- NET_WriteInt16(packet, NET_PACKET_TYPE_WAITING_DATA);
-
- // include the number of players waiting
-
- NET_WriteInt8(packet, num_players);
-
- // send the number of drone clients
-
- NET_WriteInt8(packet, NET_SV_NumDrones());
-
- // indicate whether the client is the controller
-
- NET_WriteInt8(packet, client == controller);
-
- // send the player number of this client
-
- NET_WriteInt8(packet, client->player_number);
-
- // send the addresses of all players
-
- for (i=0; i<num_players; ++i)
- {
- char *addr;
-
- // name
-
- NET_WriteString(packet, sv_players[i]->name);
-
- // address
-
- addr = NET_AddrToString(sv_players[i]->addr);
-
- NET_WriteString(packet, addr);
- }
-
- // Send the WAD and dehacked checksums of the controlling client.
-
- if (controller != NULL)
- {
- NET_WriteSHA1Sum(packet, controller->wad_sha1sum);
- NET_WriteSHA1Sum(packet, controller->deh_sha1sum);
- NET_WriteInt8(packet, controller->is_freedoom);
- }
- else
- {
- NET_WriteSHA1Sum(packet, client->wad_sha1sum);
- NET_WriteSHA1Sum(packet, client->deh_sha1sum);
- NET_WriteInt8(packet, client->is_freedoom);
- }
-
- // send packet to client and free
-
- NET_Conn_SendPacket(&client->connection, packet);
- NET_FreePacket(packet);
-}
-
static void NET_SV_PumpSendQueue(net_client_t *client)
{
net_full_ticcmd_t cmd;
int recv_index;
+ int num_players;
int i;
int starttic, endtic;
@@ -1324,7 +1489,9 @@ static void NET_SV_PumpSendQueue(net_client_t *client)
// Check if we can generate a new entry for the send queue
// using the data in recvwindow.
- for (i=0; i<MAXPLAYERS; ++i)
+ num_players = 0;
+
+ for (i=0; i<NET_MAXPLAYERS; ++i)
{
if (sv_players[i] == client)
{
@@ -1345,6 +1512,19 @@ static void NET_SV_PumpSendQueue(net_client_t *client)
return;
}
+
+ ++num_players;
+ }
+
+ // If this is a game with only a single player in it, we might
+ // be sending a ticcmd set containing 0 ticcmds. This is fine;
+ // however, there's nothing to stop the game running on ahead
+ // and never stopping. Don't let the server get too far ahead
+ // of the client.
+
+ if (num_players == 0 && client->sendseq > recvwindow_start + 10)
+ {
+ return;
}
//printf("SV: have complete ticcmd for %i\n", client->sendseq);
@@ -1357,7 +1537,7 @@ static void NET_SV_PumpSendQueue(net_client_t *client)
cmd.latency = 0;
- for (i=0; i<MAXPLAYERS; ++i)
+ for (i=0; i<NET_MAXPLAYERS; ++i)
{
net_client_recv_t *recvobj;
@@ -1458,7 +1638,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)
@@ -1489,9 +1669,19 @@ static void NET_SV_RunClient(net_client_t *client)
if (client->connection.state == NET_CONN_STATE_DISCONNECTED)
{
- // deactivate and free back
-
client->active = false;
+
+ // If we were about to start a game, any player disconnecting
+ // should cause an abort.
+
+ if (server_state == SERVER_WAITING_START && !client->drone)
+ {
+ NET_SV_BroadcastMessage("Game startup aborted because "
+ "player '%s' disconnected.",
+ client->name);
+ NET_SV_GameEnded();
+ }
+
free(client->name);
NET_FreeAddress(client->addr);
@@ -1505,7 +1695,7 @@ static void NET_SV_RunClient(net_client_t *client)
NET_SV_GameEnded();
}
}
-
+
if (!ClientConnected(client))
{
// client has not yet finished connecting
@@ -1513,7 +1703,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
@@ -1561,7 +1751,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;
}
@@ -1578,7 +1768,6 @@ static void UpdateMasterServer(void)
if (now - master_resolve_time > MASTER_RESOLVE_PERIOD * 1000)
{
net_addr_t *new_addr;
- printf("Re-resolve master server\n");
new_addr = NET_Query_ResolveMaster(server_context);
@@ -1666,17 +1855,26 @@ void NET_SV_Run(void)
}
}
- if (server_state == SERVER_IN_GAME)
+ switch (server_state)
{
- NET_SV_AdvanceWindow();
+ case SERVER_WAITING_LAUNCH:
+ break;
- for (i=0; i<MAXPLAYERS; ++i)
- {
- if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
+ case SERVER_WAITING_START:
+ CheckStartGame();
+ break;
+
+ case SERVER_IN_GAME:
+ NET_SV_AdvanceWindow();
+
+ for (i = 0; i < NET_MAXPLAYERS; ++i)
{
- NET_SV_CheckResends(sv_players[i]);
+ if (sv_players[i] != NULL && ClientConnected(sv_players[i]))
+ {
+ NET_SV_CheckResends(sv_players[i]);
+ }
}
- }
+ break;
}
}
@@ -1740,4 +1938,3 @@ void NET_SV_Shutdown(void)
I_Sleep(1);
}
}
-