X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=host.c;h=ad337c596e6d73ebc3618e1b7be6faa24fef6f22;hb=a2445d85eccf4d0c5766f44f02cd04a600c4bad4;hp=a9b94def6706cef0454b939f40fa307b086acdcf;hpb=cd4716322dec1ce6da1b9acdfe0a9a91af9d5663;p=xonotic%2Fdarkplaces.git diff --git a/host.c b/host.c index a9b94def..ad337c59 100644 --- a/host.c +++ b/host.c @@ -406,7 +406,9 @@ void SV_DropClient(qboolean crash) int i; Con_Printf("Client \"%s\" dropped\n", host_client->name); - // send any final messages (don't check for errors) + // make sure edict is not corrupt (from a level change for example) + host_client->edict = EDICT_NUM(host_client - svs.clients + 1); + if (host_client->netconnection) { // free the client (the body stays around) @@ -416,27 +418,25 @@ void SV_DropClient(qboolean crash) MSG_WriteByte(&host_client->message, svc_disconnect); NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message); } - // break the net connection NetConn_Close(host_client->netconnection); host_client->netconnection = NULL; + } - // LordHavoc: don't call QC if server is dead (avoids recursive - // Host_Error in some mods when they run out of edicts) - if (sv.active && host_client->edict && host_client->spawned) - { - // call the prog function for removing a client - // this will set the body to a dead frame, among other things - 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; - } + // call qc ClientDisconnect function + // LordHavoc: don't call QC if server is dead (avoids recursive + // Host_Error in some mods when they run out of edicts) + if (host_client->active && sv.active && host_client->edict && host_client->spawned) + { + // call the prog function for removing a client + // this will set the body to a dead frame, among other things + 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; @@ -464,6 +464,13 @@ void SV_DropClient(qboolean crash) EntityFrame4_FreeDatabase(host_client->entitydatabase4); if (host_client->entitydatabase5) EntityFrame5_FreeDatabase(host_client->entitydatabase5); + + if (sv.active) + { + // clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags + ED_ClearEdict(host_client->edict); + } + // clear the client struct (this sets active to false) memset(host_client, 0, sizeof(*host_client)); @@ -590,9 +597,23 @@ qboolean Host_FilterTime (double time) timeleft = (oldrealtime - realtime) + timecap; if (timeleft > 0) { + int msleft; // don't totally hog the CPU - if (timeleft >= 0.03) - Sys_Sleep((int)(timeleft * 1000) - 10); + if (cls.state == ca_dedicated) + { + // if dedicated, try to use as little cpu as possible by waiting + // just a little longer than necessary + // (yes this means it doesn't quite keep up with the framerate) + msleft = (int)ceil(timeleft * 1000); + } + else + { + // if not dedicated, try to hit exactly a steady framerate by not + // sleeping the full amount + msleft = (int)floor(timeleft * 1000); + } + if (msleft > 0) + Sys_Sleep(msleft); return false; } @@ -913,6 +934,7 @@ void Host_Init (void) if (cls.state != ca_dedicated) { VID_Open(); + CL_InitTEnts (); // We must wait after sound startup to load tent sounds SCR_BeginLoadingPlaque(); MR_Init(); }