X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=host.c;h=299ecad647d35f18df6ac0686fade1dcb23977de;hb=c1d9bbe13a1d1b1769f1690d94f3b49b9f16f840;hp=2ca9ade91f9753160b26b7590a828498e6b9a7a7;hpb=a0338ffd578afdaf693aee96bc6f948afb5b1844;p=xonotic%2Fdarkplaces.git diff --git a/host.c b/host.c index 2ca9ade9..299ecad6 100644 --- a/host.c +++ b/host.c @@ -132,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; @@ -158,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); @@ -180,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; @@ -213,7 +217,7 @@ void Host_ServerOptions (void) 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; } } @@ -236,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); } /* @@ -252,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); @@ -292,12 +296,12 @@ void Host_InitLocal (void) /* =============== -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; @@ -359,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); @@ -437,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); @@ -457,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)); } /* @@ -474,7 +477,6 @@ void Host_ShutdownServer(qboolean crash) int i, count; sizebuf_t buf; char message[4]; - double start; if (!sv.active) return; @@ -490,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; @@ -525,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(); @@ -535,6 +511,7 @@ void Host_ShutdownServer(qboolean crash) // clear structures // memset(&sv, 0, sizeof(sv)); + memset(svs.clients, 0, svs.maxclients*sizeof(client_t)); } @@ -569,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) @@ -582,21 +559,27 @@ qboolean Host_FilterTime (double time) 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)) - timecap = 1.0 / host_maxfps.value; + if (cls.state != ca_dedicated) + { + 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((int)(timeleft * 1000) - 5); return false; + } } // LordHavoc: copy into host_realframetime as well @@ -704,6 +687,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 @@ -713,11 +697,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(); @@ -727,15 +707,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); //------------------- // @@ -765,11 +745,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(); @@ -777,18 +757,19 @@ void _Host_Frame (float time) if (host_speeds.integer) time1 = Sys_DoubleTime(); + R_UpdateWorld(); CL_UpdateScreen(); if (host_speeds.integer) 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); @@ -807,6 +788,7 @@ void _Host_Frame (float time) host_framecount++; host_loopactive = true; + } void Host_Frame (float time) @@ -836,9 +818,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