longjmp (host_abortserver, 1);
}
+mempool_t *sv_clients_mempool = NULL;
+
void Host_ServerOptions (void)
{
int i, numplayers;
else
{
// default players in some games, singleplayer in most
- if (gamemode != GAME_TRANSFUSION && gamemode != GAME_GOODVSBAD2 && gamemode != GAME_NEXUIZ || gamemode == GAME_BATTLEMECH)
+ if (gamemode != GAME_TRANSFUSION && gamemode != GAME_GOODVSBAD2 && gamemode != GAME_NEXUIZ && gamemode != GAME_BATTLEMECH)
numplayers = 1;
}
}
numplayers = bound(1, numplayers, MAX_SCOREBOARD);
- if (numplayers > 1)
- {
- if (!deathmatch.integer)
- Cvar_SetValueQuick(&deathmatch, 1);
- }
- else
- Cvar_SetValueQuick(&deathmatch, 0);
+ if (numplayers > 1 && !deathmatch.integer)
+ Cvar_SetValueQuick(&deathmatch, 1);
- Cvar_SetValueQuick(&sv_maxplayers, numplayers);
+ svs.maxclients = numplayers;
+ sv_clients_mempool = Mem_AllocPool("server clients");
+ svs.clients = Mem_Alloc(sv_clients_mempool, sizeof(client_t) * svs.maxclients);
}
/*
vsnprintf(string, sizeof(string), fmt,argptr);
va_end(argptr);
- for (i = 0;i < MAX_SCOREBOARD;i++)
+ for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
{
- if ((client = svs.connectedclients[i]) && client->spawned)
+ if (client->spawned)
{
MSG_WriteByte(&client->message, svc_print);
MSG_WriteString(&client->message, string);
}
// send notification to all clients
- for (i = 0;i < MAX_SCOREBOARD;i++)
+ for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
{
- if (!(client = svs.connectedclients[i]))
+ if (!client->active)
continue;
MSG_WriteByte(&client->message, svc_updatename);
MSG_WriteByte(&client->message, host_client->number);
// free the client now
if (host_client->entitydatabase4)
EntityFrame4_FreeDatabase(host_client->entitydatabase4);
- // remove the index reference
- svs.connectedclients[host_client->number] = NULL;
- Mem_Free(host_client);
+ // clear the client struct (this sets active to false)
+ memset(host_client, 0, sizeof(*host_client));
}
/*
int i, count;
sizebuf_t buf;
char message[4];
- double start;
if (!sv.active)
return;
NetConn_Heartbeat(2);
NetConn_Heartbeat(2);
-// flush any pending messages - like the score!!!
- start = Sys_DoubleTime();
- do
- {
- count = 0;
- NetConn_ClientFrame();
- NetConn_ServerFrame();
- for (i = 0;i < MAX_SCOREBOARD;i++)
- {
- host_client = svs.connectedclients[i];
- if (host_client && host_client->message.cursize)
- {
- if (NetConn_CanSendMessage(host_client->netconnection))
- {
- NetConn_SendReliableMessage(host_client->netconnection, &host_client->message);
- SZ_Clear(&host_client->message);
- }
- else
- count++;
- }
- }
- if ((Sys_DoubleTime() - start) > 3.0)
- break;
- }
- while(count);
-
// make sure all the clients know we're disconnecting
buf.data = message;
buf.maxsize = 4;
if (count)
Con_Printf("Host_ShutdownServer: NetConn_SendToAll failed for %u clients\n", count);
- for (i = 0;i < MAX_SCOREBOARD;i++)
- if ((host_client = svs.connectedclients[i]))
+ for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+ if (host_client->active)
SV_DropClient(crash); // server shutdown
NetConn_CloseServerPorts();
// clear structures
//
memset(&sv, 0, sizeof(sv));
+ memset(svs.clients, 0, svs.maxclients*sizeof(client_t));
}
extern cvar_t cl_avidemo;
qboolean Host_FilterTime (double time)
{
- double timecap;
+ double timecap, timeleft;
realtime += time;
if (slowmo.value < 0.0f)
Cvar_SetValue("cl_avidemo", 0.0f);
// check if framerate is too high
- if (cl_avidemo.value >= 0.1f)
+ if (!cls.timedemo)
{
- timecap = 1.0 / (double)cl_avidemo.value;
- if ((realtime - oldrealtime) < timecap)
- return false;
- }
- else if (!cls.timedemo)
- {
- // default to sys_ticrate (server framerate - presumably low) unless we're the active window and either connected to a server or playing a video
+ // default to sys_ticrate (server framerate - presumably low) unless we
+ // have a good reason to run faster
timecap = sys_ticrate.value;
- if (vid_activewindow && (cls.state == ca_connected || cl_videoplaying))
+ if (cl_avidemo.value >= 0.1f)
+ timecap = 1.0 / (double)cl_avidemo.value;
+ else if (vid_activewindow && !scr_con_current)
timecap = 1.0 / host_maxfps.value;
- if ((realtime - oldrealtime) < timecap)
+ timeleft = oldrealtime + timecap - realtime;
+ if (timeleft > 0)
+ {
+ // don't totally hog the CPU
+ if (timeleft >= 0.02)
+ Sys_Sleep();
return false;
+ }
}
// LordHavoc: copy into host_realframetime as well
// decide the simulation time
if (!Host_FilterTime(time))
- {
- // if time was rejected, don't totally hog the CPU
- Sys_Sleep();
return;
- }
cl.islocalgame = NetConn_IsLocalGame();
timecount = 0;
timetotal = 0;
c = 0;
- for (i = 0;i < MAX_SCOREBOARD;i++)
- if (svs.connectedclients[i])
+ for (i=0 ; i<svs.maxclients ; i++)
+ {
+ if (svs.clients[i].active)
c++;
+ }
Con_Printf ("serverprofile: %2i clients %2i msec\n", c, m);
}
V_Init();
COM_Init();
Host_InitLocal();
- W_LoadWadFile("gfx.wad");
Key_Init();
Con_Init();
Chase_Init();
Con_DPrintf ("========Initialized=========\n");
if (cls.state != ca_dedicated)
+ {
VID_Open();
+ SCR_BeginLoadingPlaque();
+ }
}