X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=host.c;h=89e5dab93e4f1ba2296262eb3a8d4b68850623e0;hb=c218cedd2533732ee59de007261f2be25e605897;hp=50392158c3804dc13056d8ac0dcc35d0fa908443;hpb=8da4459b59336acc54dd028e44177756cbfa48cd;p=xonotic%2Fdarkplaces.git diff --git a/host.c b/host.c index 50392158..89e5dab9 100644 --- a/host.c +++ b/host.c @@ -96,8 +96,6 @@ cvar_t temp1 = {0, "temp1","0"}; cvar_t timestamps = {CVAR_SAVE, "timestamps", "0"}; cvar_t timeformat = {CVAR_SAVE, "timeformat", "[%b %e %X] "}; -cvar_t sv_maxplayers = {0, "maxplayers", "8"}; - /* ================ Host_EndGame @@ -134,11 +132,10 @@ Host_Error This shuts down both the client and server ================ */ +void PRVM_ProcessError(void); static char hosterrorstring1[4096]; static char hosterrorstring2[4096]; static qboolean hosterror = false; -extern char sv_spawnmap[MAX_QPATH]; -extern char sv_loadgame[MAX_OSPATH]; void Host_Error (const char *error, ...) { va_list argptr; @@ -160,14 +157,17 @@ void Host_Error (const char *error, ...) strcpy(hosterrorstring2, hosterrorstring1); - // make sure we don't get in a loading loop - sv_loadgame[0] = 0; - sv_spawnmap[0] = 0; - CL_Parse_DumpPacket(); PR_Crash(); + //PRVM_Crash(); // crash current prog + + // crash all prvm progs + PRVM_CrashAll(); + + PRVM_ProcessError(); + if (sv.active) Host_ShutdownServer (false); @@ -182,6 +182,8 @@ void Host_Error (const char *error, ...) longjmp (host_abortserver, 1); } +mempool_t *sv_clients_mempool = NULL; + void Host_ServerOptions (void) { int i, numplayers; @@ -238,15 +240,12 @@ void Host_ServerOptions (void) 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); } /* @@ -254,9 +253,12 @@ void Host_ServerOptions (void) Host_InitLocal ====================== */ +void Host_SaveConfig_f(void); void Host_InitLocal (void) { Host_InitCommands (); + + Cmd_AddCommand("saveconfig", Host_SaveConfig_f); Cvar_RegisterVariable (&host_framerate); Cvar_RegisterVariable (&host_speeds); @@ -288,20 +290,18 @@ void Host_InitLocal (void) Cvar_RegisterVariable (×tamps); Cvar_RegisterVariable (&timeformat); - Cvar_RegisterVariable(&sv_maxplayers); - Host_ServerOptions (); } /* =============== -Host_WriteConfiguration +Host_SaveConfig_f Writes key bindings and archived cvars to config.cfg =============== */ -void Host_WriteConfiguration (void) +void Host_SaveConfig_f(void) { qfile_t *f; @@ -363,9 +363,9 @@ void SV_BroadcastPrintf(const char *fmt, ...) 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); @@ -441,9 +441,9 @@ void SV_DropClient(qboolean crash) } // 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); @@ -461,9 +461,8 @@ void SV_DropClient(qboolean crash) // 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)); } /* @@ -478,7 +477,6 @@ void Host_ShutdownServer(qboolean crash) int i, count; sizebuf_t buf; char message[4]; - double start; if (!sv.active) return; @@ -494,32 +492,6 @@ void Host_ShutdownServer(qboolean crash) 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; @@ -529,8 +501,8 @@ void Host_ShutdownServer(qboolean crash) 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(); @@ -539,6 +511,7 @@ void Host_ShutdownServer(qboolean crash) // clear structures // memset(&sv, 0, sizeof(sv)); + memset(svs.clients, 0, svs.maxclients*sizeof(client_t)); } @@ -573,7 +546,7 @@ Returns false if the time is too short to run a frame extern cvar_t cl_avidemo; qboolean Host_FilterTime (double time) { - double timecap; + double timecap, timeleft; realtime += time; if (slowmo.value < 0.0f) @@ -586,21 +559,24 @@ qboolean Host_FilterTime (double time) Cvar_SetValue("cl_avidemo", 0.0f); // check if framerate is too high - if (cl_avidemo.value >= 0.1f) - { - timecap = 1.0 / (double)cl_avidemo.value; - if ((realtime - oldrealtime) < timecap) - return false; - } - else if (!cls.timedemo) + 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) 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 @@ -708,6 +684,7 @@ void _Host_Frame (float time) static double time2 = 0; static double time3 = 0; int pass1, pass2, pass3; + usercmd_t cmd; // Used for receiving input if (setjmp(host_abortserver)) return; // something bad happened, or the server disconnected @@ -717,11 +694,7 @@ void _Host_Frame (float time) // 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(); @@ -731,15 +704,15 @@ void _Host_Frame (float time) // allow mice or other external controllers to add commands IN_Commands(); + // Collect input into cmd + IN_ProcessMove(&cmd); + // process console commands Cbuf_Execute(); - // LordHavoc: map and load are delayed until video is initialized - Host_PerformSpawnServerAndLoadGame(); - // if running the server locally, make intentions now if (cls.state == ca_connected && sv.active) - CL_SendCmd(); + CL_SendCmd(&cmd); //------------------- // @@ -769,11 +742,11 @@ void _Host_Frame (float time) // if running the server remotely, send intentions now after // the incoming messages have been read if (!sv.active) - CL_SendCmd(); + CL_SendCmd(&cmd); CL_ReadFromServer(); } - ui_update(); + //ui_update(); CL_VideoFrame(); @@ -787,12 +760,12 @@ void _Host_Frame (float time) time2 = Sys_DoubleTime(); // update audio - if (cls.signon == SIGNONS) + if (cls.signon == SIGNONS && cl.viewentity >= 0 && cl.viewentity < MAX_EDICTS && cl_entities[cl.viewentity].state_current.active) { // LordHavoc: this used to use renderer variables (eww) - vec3_t forward, right, up; - AngleVectors(cl.viewangles, forward, right, up); - S_Update(cl_entities[cl.viewentity].render.origin, forward, right, up); + vec3_t forward, left, up, origin; + Matrix4x4_ToVectors(&cl_entities[cl.viewentity].render.matrix, forward, left, up, origin); + S_Update(origin, forward, left, up); } else S_Update(vec3_origin, vec3_origin, vec3_origin, vec3_origin); @@ -811,6 +784,7 @@ void _Host_Frame (float time) host_framecount++; host_loopactive = true; + } void Host_Frame (float time) @@ -840,9 +814,11 @@ void Host_Frame (float time) timecount = 0; timetotal = 0; c = 0; - for (i = 0;i < MAX_SCOREBOARD;i++) - if (svs.connectedclients[i]) + for (i=0 ; i