// general default
numplayers = 8;
+// COMMANDLINEOPTION: Server: -dedicated [playerlimit] starts a dedicated server (with a command console), default playerlimit is 8
+// COMMANDLINEOPTION: Server: -listen [playerlimit] starts a multiplayer server with graphical client, like singleplayer but other players can connect, default playerlimit is 8
if (cl_available)
{
// client exists, check what mode the user wants
Cvar_SetValueQuick(&deathmatch, 1);
svs.maxclients = numplayers;
- sv_clients_mempool = Mem_AllocPool("server clients");
+ sv_clients_mempool = Mem_AllocPool("server clients", 0, NULL);
svs.clients = Mem_Alloc(sv_clients_mempool, sizeof(client_t) * svs.maxclients);
}
*/
void SV_DropClient(qboolean crash)
{
- int saveSelf;
int i;
- client_t *client;
-
Con_Printf("Client \"%s\" dropped\n", host_client->name);
// send any final messages (don't check for errors)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
- saveSelf = pr_global_struct->self;
+ int saveSelf = pr_global_struct->self;
pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
PR_ExecuteProgram(pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing");
pr_global_struct->self = saveSelf;
}
}
+ // remove leaving player from scoreboard
+ // clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags
+ ED_ClearEdict(host_client->edict);
+ //host_client->edict->v->netname = PR_SetString(host_client->name);
+ //if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
+ // val->_float = 0;
+ //host_client->edict->v->frags = 0;
+ host_client->name[0] = 0;
+ host_client->colors = 0;
+ host_client->frags = 0;
// send notification to all clients
- for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
- {
- if (!client->active)
- continue;
- MSG_WriteByte(&client->message, svc_updatename);
- MSG_WriteByte(&client->message, host_client->number);
- MSG_WriteString(&client->message, "");
- MSG_WriteByte(&client->message, svc_updatefrags);
- MSG_WriteByte(&client->message, host_client->number);
- MSG_WriteShort(&client->message, 0);
- MSG_WriteByte(&client->message, svc_updatecolors);
- MSG_WriteByte(&client->message, host_client->number);
- MSG_WriteByte(&client->message, 0);
- }
-
- NetConn_Heartbeat(1);
+ // get number of client manually just to make sure we get it right...
+ i = host_client - svs.clients;
+ MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
+ MSG_WriteByte (&sv.reliable_datagram, i);
+ MSG_WriteString (&sv.reliable_datagram, host_client->name);
+ MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
+ MSG_WriteByte (&sv.reliable_datagram, i);
+ MSG_WriteByte (&sv.reliable_datagram, host_client->colors);
+ MSG_WriteByte (&sv.reliable_datagram, svc_updatefrags);
+ MSG_WriteByte (&sv.reliable_datagram, i);
+ MSG_WriteShort (&sv.reliable_datagram, host_client->frags);
// free the client now
+ if (host_client->entitydatabase)
+ EntityFrame_FreeDatabase(host_client->entitydatabase);
if (host_client->entitydatabase4)
EntityFrame4_FreeDatabase(host_client->entitydatabase4);
+ if (host_client->entitydatabase5)
+ EntityFrame5_FreeDatabase(host_client->entitydatabase5);
// clear the client struct (this sets active to false)
memset(host_client, 0, sizeof(*host_client));
+
+ // update server listing on the master because player count changed
+ // (which the master uses for filtering empty/full servers)
+ NetConn_Heartbeat(1);
}
/*
if (host_speeds.integer)
time1 = Sys_DoubleTime();
- R_UpdateWorld();
CL_UpdateScreen();
if (host_speeds.integer)
srand(time(NULL));
// FIXME: this is evil, but possibly temporary
+// COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers)
if (COM_CheckParm("-developer"))
{
forcedeveloper = true;
if (cls.state != ca_dedicated)
{
Palette_Init();
+ MR_Init_Commands();
VID_Shared_Init();
VID_Init();
Cbuf_InsertText("exec quake.rc\n");
// check for special benchmark mode
+// COMMANDLINEOPTION: Client: -benchmark <demoname> runs a timedemo and quits, results of any timedemo can be found in gamedir/benchmark.log (for example id1/benchmark.log)
i = COM_CheckParm("-benchmark");
if (i && i + 1 < com_argc)
Cbuf_InsertText(va("timedemo %s\n", com_argv[i + 1]));
}
isdown = true;
+ // disconnect client from server if active
+ CL_Disconnect();
+
+ // shut down local server if active
+ Host_ShutdownServer (false);
+
// Shutdown menu
if(MR_Shutdown)
MR_Shutdown();
}
Sys_Shutdown();
+ Log_Close ();
}