]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host.c
very very minor optimization
[xonotic/darkplaces.git] / host.c
diff --git a/host.c b/host.c
index 3d52666e3d16f8396570a00310cc6bec0515bf1f..7e281db30c33c3ff9566f6657acf0cdc00ee81c6 100644 (file)
--- a/host.c
+++ b/host.c
@@ -39,7 +39,7 @@ Memory is cleared / released when a server or client begins, not when they end.
 
 // how many frames have occurred
 // (checked by Host_Error and Host_SaveConfig_f)
-int host_framecount;
+int host_framecount = 0;
 // LordHavoc: set when quit is executed
 qboolean host_shuttingdown = false;
 
@@ -51,9 +51,6 @@ double realtime;
 // realtime from previous frame
 double oldrealtime;
 
-// used for -developer commandline parameter, hacky hacky
-int forcedeveloper;
-
 // current client
 client_t *host_client;
 
@@ -122,6 +119,9 @@ void Host_Error (const char *error, ...)
        static qboolean hosterror = false;
        va_list argptr;
 
+       // turn off rcon redirect if it was active when the crash occurred
+       rcon_redirect = false;
+
        va_start (argptr,error);
        dpvsnprintf (hosterrorstring1,sizeof(hosterrorstring1),error,argptr);
        va_end (argptr);
@@ -141,13 +141,15 @@ void Host_Error (const char *error, ...)
 
        CL_Parse_DumpPacket();
 
+       CL_Parse_ErrorCleanUp();
+
        //PR_Crash();
 
        // print out where the crash happened, if it was caused by QC (and do a cleanup)
        PRVM_Crash();
 
 
-       Host_ShutdownServer (false);
+       Host_ShutdownServer ();
 
        if (cls.state == ca_dedicated)
                Sys_Error ("Host_Error: %s",hosterrorstring2);  // dedicated servers exit
@@ -238,8 +240,6 @@ void Host_InitLocal (void)
        Cvar_RegisterVariable (&noexit);
        Cvar_RegisterVariable (&skill);
        Cvar_RegisterVariable (&developer);
-       if (forcedeveloper) // make it real now that the cvar is registered
-               Cvar_SetValue("developer", 1);
        Cvar_RegisterVariable (&developer_entityparsing);
        Cvar_RegisterVariable (&deathmatch);
        Cvar_RegisterVariable (&coop);
@@ -294,8 +294,11 @@ FIXME: make this just a stuffed echo?
 */
 void SV_ClientPrint(const char *msg)
 {
-       MSG_WriteByte(&host_client->message, svc_print);
-       MSG_WriteString(&host_client->message, msg);
+       if (host_client->netconnection)
+       {
+               MSG_WriteByte(&host_client->netconnection->message, svc_print);
+               MSG_WriteString(&host_client->netconnection->message, msg);
+       }
 }
 
 /*
@@ -332,10 +335,10 @@ void SV_BroadcastPrint(const char *msg)
 
        for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
        {
-               if (client->spawned)
+               if (client->spawned && client->netconnection)
                {
-                       MSG_WriteByte(&client->message, svc_print);
-                       MSG_WriteString(&client->message, msg);
+                       MSG_WriteByte(&client->netconnection->message, svc_print);
+                       MSG_WriteString(&client->netconnection->message, msg);
                }
        }
 
@@ -374,12 +377,15 @@ void Host_ClientCommands(const char *fmt, ...)
        va_list argptr;
        char string[MAX_INPUTLINE];
 
+       if (!host_client->netconnection)
+               return;
+
        va_start(argptr,fmt);
        dpvsnprintf(string, sizeof(string), fmt, argptr);
        va_end(argptr);
 
-       MSG_WriteByte(&host_client->message, svc_stufftext);
-       MSG_WriteString(&host_client->message, string);
+       MSG_WriteByte(&host_client->netconnection->message, svc_stufftext);
+       MSG_WriteString(&host_client->netconnection->message, string);
 }
 
 /*
@@ -404,10 +410,15 @@ void SV_DropClient(qboolean crash)
                if (!crash)
                {
                        // LordHavoc: no opportunity for resending, so use unreliable 3 times
-                       MSG_WriteByte(&host_client->message, svc_disconnect);
-                       NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message);
-                       NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message);
-                       NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message);
+                       unsigned char bufdata[8];
+                       sizebuf_t buf;
+                       memset(&buf, 0, sizeof(buf));
+                       buf.data = bufdata;
+                       buf.maxsize = sizeof(bufdata);
+                       MSG_WriteByte(&buf, svc_disconnect);
+                       NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol);
+                       NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol);
+                       NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol);
                }
                // break the net connection
                NetConn_Close(host_client->netconnection);
@@ -478,11 +489,9 @@ Host_ShutdownServer
 This only happens at the end of a game, not between levels
 ==================
 */
-void Host_ShutdownServer(qboolean crash)
+void Host_ShutdownServer(void)
 {
-       int i, count;
-       sizebuf_t buf;
-       unsigned char message[4];
+       int i;
 
        Con_DPrintf("Host_ShutdownServer\n");
 
@@ -493,18 +502,10 @@ void Host_ShutdownServer(qboolean crash)
        NetConn_Heartbeat(2);
 
 // make sure all the clients know we're disconnecting
-       buf.data = message;
-       buf.maxsize = 4;
-       buf.cursize = 0;
-       MSG_WriteByte(&buf, svc_disconnect);
-       count = NetConn_SendToAll(&buf, 5);
-       if (count)
-               Con_Printf("Host_ShutdownServer: NetConn_SendToAll failed for %u clients\n", count);
-
        SV_VM_Begin();
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
                if (host_client->active)
-                       SV_DropClient(crash); // server shutdown
+                       SV_DropClient(false); // server shutdown
        SV_VM_End();
 
        NetConn_CloseServerPorts();
@@ -518,25 +519,6 @@ void Host_ShutdownServer(qboolean crash)
 }
 
 
-/*
-================
-Host_ClearMemory
-
-This clears all the memory used by both the client and server, but does
-not reinitialize anything.
-================
-*/
-void Host_ClearMemory (void)
-{
-       Con_DPrint("Clearing memory\n");
-       Mod_ClearAll ();
-
-       cls.signon = 0;
-       memset (&sv, 0, sizeof(sv));
-       memset (&cl, 0, sizeof(cl));
-}
-
-
 //============================================================================
 
 /*
@@ -546,9 +528,6 @@ Host_FilterTime
 Returns false if the time is too short to run a frame
 ===================
 */
-extern qboolean cl_capturevideo_active;
-extern double cl_capturevideo_framerate;
-extern qfile_t *cl_capturevideo_soundfile;
 qboolean Host_FilterTime (double time)
 {
        double timecap, timeleft;
@@ -579,8 +558,8 @@ qboolean Host_FilterTime (double time)
                timecap = sys_ticrate.value;
        if (cls.state != ca_dedicated)
        {
-               if (cl_capturevideo_active)
-                       timecap = 1.0 / cl_capturevideo_framerate;
+               if (cls.capturevideo_active)
+                       timecap = 1.0 / cls.capturevideo_framerate;
                else if (vid_activewindow)
                        timecap = 1.0 / cl_maxfps.value;
        }
@@ -606,7 +585,7 @@ qboolean Host_FilterTime (double time)
        host_realframetime = host_frametime = realtime - oldrealtime;
        oldrealtime = realtime;
 
-       if (cl_capturevideo_active && !cl_capturevideo_soundfile)
+       if (cls.capturevideo_active && !cls.capturevideo_soundfile)
                host_frametime = timecap;
 
        // apply slowmo scaling
@@ -654,12 +633,12 @@ Host_ServerFrame
 */
 void Host_ServerFrame (void)
 {
-       // never run more than 1 frame per call because multiple frames per call it
-       // does not handle overload gracefully, slowing down is better than a
-       // sudden significant drop in framerate (or worse, freezing until the
-       // problem goes away)
-       int framecount, framelimit = 1;
-       double advancetime;
+       // execute one or more server frames, with an upper limit on how much
+       // execution time to spend on server frames to avoid freezing the game if
+       // the server is overloaded, this execution time limit means the game will
+       // slow down if the server is taking too long.
+       int framecount, framelimit = 100;
+       double advancetime, aborttime;
        if (!sv.active)
        {
                sv.timer = 0;
@@ -667,18 +646,22 @@ void Host_ServerFrame (void)
        }
        sv.timer += host_realframetime;
 
-
        // run the world state
        // don't allow simulation to run too fast or too slow or logic glitches can occur
+
+       // setup the VM frame
+       SV_VM_Begin();
+       // stop running server frames if the wall time reaches this value
+       aborttime = Sys_DoubleTime() + 0.1;
        for (framecount = 0;framecount < framelimit && sv.timer > 0;framecount++)
        {
-               // setup the VM frame
-               SV_VM_Begin();
-
-               if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
+               if (sys_ticrate.value <= 0)
+                       advancetime = sv.timer;
+               else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
                        advancetime = min(sv.timer, sys_ticrate.value);
                else
                        advancetime = sys_ticrate.value;
+               advancetime = min(advancetime, 0.1);
                sv.timer -= advancetime;
 
                // only advance time if not paused
@@ -689,12 +672,6 @@ void Host_ServerFrame (void)
                if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive)))
                        sv.frametime = 0;
 
-               // set the time and clear the general datagram
-               SV_ClearDatagram();
-
-               // check for network packets to the server each world step incase they
-               // come in midframe (particularly if host is running really slow)
-               NetConn_ServerFrame();
 
                // move things around and think unless paused
                if (sv.frametime)
@@ -703,13 +680,19 @@ void Host_ServerFrame (void)
                // send all messages to the clients
                SV_SendClientMessages();
 
-               // send an heartbeat if enough time has passed since the last one
-               NetConn_Heartbeat(0);
+               // clear the general datagram
+               SV_ClearDatagram();
 
-               // end the server VM frame
-               SV_VM_End();
+               // if this server frame took too long, break out of the loop
+               if (Sys_DoubleTime() >= aborttime)
+                       break;
        }
 
+       // end the server VM frame
+       SV_VM_End();
+
+       // send an heartbeat if enough time has passed since the last one
+       NetConn_Heartbeat(0);
 
        // if we fell behind too many frames just don't worry about it
        if (sv.timer > 0)
@@ -753,8 +736,8 @@ void _Host_Frame (float time)
        Cbuf_Execute();
 
        // if running the server locally, make intentions now
-       if (cls.state == ca_connected && sv.active)
-               CL_SendCmd();
+       //if (cl.islocalgame)
+       //      CL_SendCmd();
 
 //-------------------
 //
@@ -762,6 +745,11 @@ void _Host_Frame (float time)
 //
 //-------------------
 
+       // receive server packets now, which might contain rcon commands, which
+       // may change level or other such things we don't want to have happen in
+       // the middle of Host_Frame
+       NetConn_ServerFrame();
+
        // check for commands typed to the host
        Host_GetConsoleCommands();
 
@@ -781,11 +769,11 @@ void _Host_Frame (float time)
 
        if (cls.state == ca_connected)
        {
+               CL_ReadFromServer();
                // if running the server remotely, send intentions now after
                // the incoming messages have been read
-               if (!sv.active)
-                       CL_SendCmd();
-               CL_ReadFromServer();
+               //if (!cl.islocalgame)
+               //      CL_SendCmd();
        }
 
        //ui_update();
@@ -898,6 +886,24 @@ void Host_Init (void)
        int i;
        const char* os;
 
+       // FIXME: this is evil, but possibly temporary
+// COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers)
+       if (COM_CheckParm("-developer"))
+       {
+               developer.value = developer.integer = 100;
+               developer.string = "100";
+       }
+
+       if (COM_CheckParm("-developer2"))
+       {
+               developer.value = developer.integer = 100;
+               developer.string = "100";
+               developer_memory.value = developer_memory.integer = 100;
+               developer.string = "100";
+               developer_memorydebug.value = developer_memorydebug.integer = 100;
+               developer_memorydebug.string = "100";
+       }
+
        // LordHavoc: quake never seeded the random number generator before... heh
        srand(time(NULL));
 
@@ -932,6 +938,8 @@ void Host_Init (void)
        os = "OpenBSD";
 #elif defined(MACOSX)
        os = "Mac OS X";
+#elif defined(__MORPHOS__)
+       os = "MorphOS";
 #else
        os = "Unknown";
 #endif
@@ -943,15 +951,6 @@ void Host_Init (void)
        else
                Con_Printf("%s\n", engineversion);
 
-       // 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;
-               developer.integer = 1;
-               developer.value = 1;
-       }
-
        // initialize filesystem (including fs_basedir, fs_gamedir, -path, -game, scr_screenshot_name)
        FS_Init();
 
@@ -1000,8 +999,6 @@ void Host_Init (void)
                Cbuf_AddText("alias startmap_sp \"map nehstart\"\nalias startmap_dm \"map nehstart\"\nexec quake.rc\n");
        else if (gamemode == GAME_TRANSFUSION)
                Cbuf_AddText("alias startmap_sp \"map e1m1\"\n""alias startmap_dm \"map bb1\"\nexec quake.rc\n");
-       else if (gamemode == GAME_NEXUIZ)
-               Cbuf_AddText("alias startmap_sp \"map nexdm01\"\nalias startmap_dm \"map nexdm01\"\nexec quake.rc\n");
        else if (gamemode == GAME_TEU)
                Cbuf_AddText("alias startmap_sp \"map start\"\nalias startmap_dm \"map start\"\nexec teu.rc\n");
        else
@@ -1015,12 +1012,11 @@ void Host_Init (void)
                Cbuf_Execute();
        }
 
-       // save console log up to this point to log_file if it was set by configs
-       Log_Start();
+       // put up the loading image so the user doesn't stare at a black screen...
+       SCR_BeginLoadingPlaque();
 
        // FIXME: put this into some neat design, but the menu should be allowed to crash
        // without crashing the whole game, so this should just be a short-time solution
-       Host_StartVideo();
 
        // here comes the not so critical stuff
        if (setjmp(host_abortframe)) {
@@ -1080,7 +1076,7 @@ void Host_Init (void)
 
        Con_DPrint("========Initialized=========\n");
 
-       Host_StartVideo();
+       //Host_StartVideo();
 }
 
 
@@ -1110,7 +1106,7 @@ void Host_Shutdown(void)
        CL_Disconnect();
 
        // shut down local server if active
-       Host_ShutdownServer (false);
+       Host_ShutdownServer ();
 
        // Shutdown menu
        if(MR_Shutdown)