]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host.c
Split the global cmd interpreter into 4 separate ones for specific uses (client conso...
[xonotic/darkplaces.git] / host.c
diff --git a/host.c b/host.c
index a54067af5250d3d20aaba69fe285f418f5a3e019..5c159c018dd740f869a36844e094bd95f0ebc20f 100644 (file)
--- a/host.c
+++ b/host.c
@@ -23,14 +23,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <time.h>
 #include "libcurl.h"
-#ifdef CONFIG_CD
 #include "cdaudio.h"
-#endif
 #include "cl_video.h"
 #include "progsvm.h"
 #include "csprogs.h"
 #include "sv_demo.h"
 #include "snd_main.h"
+#include "taskqueue.h"
 #include "thread.h"
 #include "utf8lib.h"
 
@@ -48,7 +47,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 = 0;
-// LordHavoc: set when quit is executed
+// LadyHavoc: set when quit is executed
 qboolean host_shuttingdown = false;
 
 // the accumulated mainloop time since application started (with filtering), without any slowmo or clamping
@@ -132,7 +131,7 @@ void Host_Error (const char *error, ...)
 
        Con_Printf("Host_Error: %s\n", hosterrorstring1);
 
-       // LordHavoc: if crashing very early, or currently shutting down, do
+       // LadyHavoc: if crashing very early, or currently shutting down, do
        // Sys_Error instead
        if (host_framecount < 3 || host_shuttingdown)
                Sys_Error ("Host_Error: %s", hosterrorstring1);
@@ -212,7 +211,7 @@ static void Host_ServerOptions (void)
                else
                {
                        // default players in some games, singleplayer in most
-                       if (gamemode != GAME_GOODVSBAD2 && gamemode != GAME_NEXUIZ && gamemode != GAME_XONOTIC && gamemode != GAME_BATTLEMECH)
+                       if (gamemode != GAME_GOODVSBAD2 && !IS_NEXUIZ_DERIVED(gamemode) && gamemode != GAME_BATTLEMECH)
                                svs.maxclients = 1;
                }
        }
@@ -230,14 +229,16 @@ static void Host_ServerOptions (void)
 Host_InitLocal
 ======================
 */
-void Host_SaveConfig_f(void);
-void Host_LoadConfig_f(void);
+void Host_SaveConfig_f(cmd_state_t *cmd);
+void Host_LoadConfig_f(cmd_state_t *cmd);
 extern cvar_t sv_writepicture_quality;
 extern cvar_t r_texture_jpeg_fastpicmip;
 static void Host_InitLocal (void)
 {
-       Cmd_AddCommand("saveconfig", Host_SaveConfig_f, "save settings to config.cfg (or a specified filename) immediately (also automatic when quitting)");
-       Cmd_AddCommand("loadconfig", Host_LoadConfig_f, "reset everything and reload configs");
+       Cmd_AddCommand(&cmd_client, "saveconfig", Host_SaveConfig_f, "save settings to config.cfg (or a specified filename) immediately (also automatic when quitting)");
+       Cmd_AddCommand(&cmd_client, "loadconfig", Host_LoadConfig_f, "reset everything and reload configs");
+       Cmd_AddCommand(&cmd_server, "saveconfig", Host_SaveConfig_f, "save settings to config.cfg (or a specified filename) immediately (also automatic when quitting)");
+       Cmd_AddCommand(&cmd_server, "loadconfig", Host_LoadConfig_f, "reset everything and reload configs");
 
        Cvar_RegisterVariable (&cl_maxphysicsframesperserverframe);
        Cvar_RegisterVariable (&host_framerate);
@@ -283,7 +284,7 @@ static void Host_SaveConfig_to(const char *file)
 
 // dedicated servers initialize the host but don't parse and set the
 // config.cfg cvars
-       // LordHavoc: don't save a config if it crashed in startup
+       // LadyHavoc: don't save a config if it crashed in startup
        if (host_framecount >= 3 && cls.state != ca_dedicated && !COM_CheckParm("-benchmark") && !COM_CheckParm("-capturedemo"))
        {
                f = FS_OpenRealFile(file, "wb", false);
@@ -303,30 +304,30 @@ void Host_SaveConfig(void)
 {
        Host_SaveConfig_to(CONFIGFILENAME);
 }
-void Host_SaveConfig_f(void)
+void Host_SaveConfig_f(cmd_state_t *cmd)
 {
        const char *file = CONFIGFILENAME;
 
-       if(Cmd_Argc() >= 2) {
-               file = Cmd_Argv(1);
+       if(Cmd_Argc(cmd) >= 2) {
+               file = Cmd_Argv(cmd, 1);
                Con_Printf("Saving to %s\n", file);
        }
 
        Host_SaveConfig_to(file);
 }
 
-static void Host_AddConfigText(void)
+static void Host_AddConfigText(cmd_state_t *cmd)
 {
        // set up the default startmap_sp and startmap_dm aliases (mods can
        // override these) and then execute the quake.rc startup script
        if (gamemode == GAME_NEHAHRA)
-               Cbuf_InsertText("alias startmap_sp \"map nehstart\"\nalias startmap_dm \"map nehstart\"\nexec " STARTCONFIGFILENAME "\n");
+               Cbuf_InsertText(cmd, "alias startmap_sp \"map nehstart\"\nalias startmap_dm \"map nehstart\"\nexec " STARTCONFIGFILENAME "\n");
        else if (gamemode == GAME_TRANSFUSION)
-               Cbuf_InsertText("alias startmap_sp \"map e1m1\"\n""alias startmap_dm \"map bb1\"\nexec " STARTCONFIGFILENAME "\n");
+               Cbuf_InsertText(cmd, "alias startmap_sp \"map e1m1\"\n""alias startmap_dm \"map bb1\"\nexec " STARTCONFIGFILENAME "\n");
        else if (gamemode == GAME_TEU)
-               Cbuf_InsertText("alias startmap_sp \"map start\"\nalias startmap_dm \"map start\"\nexec teu.rc\n");
+               Cbuf_InsertText(cmd, "alias startmap_sp \"map start\"\nalias startmap_dm \"map start\"\nexec teu.rc\n");
        else
-               Cbuf_InsertText("alias startmap_sp \"map start\"\nalias startmap_dm \"map start\"\nexec " STARTCONFIGFILENAME "\n");
+               Cbuf_InsertText(cmd, "alias startmap_sp \"map start\"\nalias startmap_dm \"map start\"\nexec " STARTCONFIGFILENAME "\n");
 }
 
 /*
@@ -336,16 +337,16 @@ Host_LoadConfig_f
 Resets key bindings and cvars to defaults and then reloads scripts
 ===============
 */
-void Host_LoadConfig_f(void)
+void Host_LoadConfig_f(cmd_state_t *cmd)
 {
        // reset all cvars, commands and aliases to init values
        Cmd_RestoreInitState();
 #ifdef CONFIG_MENU
        // prepend a menu restart command to execute after the config
-       Cbuf_InsertText("\nmenu_restart\n");
+       Cbuf_InsertText(&cmd_client, "\nmenu_restart\n");
 #endif
        // reset cvars to their defaults, and then exec startup scripts again
-       Host_AddConfigText();
+       Host_AddConfigText(&cmd_client);
 }
 
 /*
@@ -476,7 +477,7 @@ void SV_DropClient(qboolean crash)
                // tell the client to be gone
                if (!crash)
                {
-                       // LordHavoc: no opportunity for resending, so use unreliable 3 times
+                       // LadyHavoc: no opportunity for resending, so use unreliable 3 times
                        unsigned char bufdata[8];
                        sizebuf_t buf;
                        memset(&buf, 0, sizeof(buf));
@@ -490,7 +491,7 @@ void SV_DropClient(qboolean crash)
        }
 
        // call qc ClientDisconnect function
-       // LordHavoc: don't call QC if server is dead (avoids recursive
+       // LadyHavoc: don't call QC if server is dead (avoids recursive
        // Host_Error in some mods when they run out of edicts)
        if (host_client->clientconnectcalled && sv.active && host_client->edict)
        {
@@ -633,14 +634,14 @@ Add them exactly as if they had been typed at the console
 */
 static void Host_GetConsoleCommands (void)
 {
-       char *cmd;
+       char *line;
 
-       while (1)
+       while ((line = Sys_ConsoleInput()))
        {
-               cmd = Sys_ConsoleInput ();
-               if (!cmd)
-                       break;
-               Cbuf_AddText (cmd);
+               if (cls.state == ca_dedicated)
+                       Cbuf_AddText(&cmd_server, line);
+               else
+                       Cbuf_AddText(&cmd_client, line);
        }
 }
 
@@ -679,6 +680,7 @@ void Host_Main(void)
        Host_Init();
 
        realtime = 0;
+       host_dirtytime = Sys_DirtyTime();
        for (;;)
        {
                if (setjmp(host_abortframe))
@@ -746,6 +748,8 @@ void Host_Main(void)
                if (host_framerate.value < 0.00001 && host_framerate.value != 0)
                        Cvar_SetValue("host_framerate", 0);
 
+               TaskQueue_Frame(false);
+
                // keep the random time dependent, but not when playing demos/benchmarking
                if(!*sv_random_seed.string && !cls.demoplayback)
                        rand();
@@ -777,7 +781,8 @@ void Host_Main(void)
                        // process console commands
 //                     R_TimeReport("preconsole");
                        CL_VM_PreventInformationLeaks();
-                       Cbuf_Frame();
+                       Cbuf_Frame(&cmd_client);
+                       Cbuf_Frame(&cmd_server);
 //                     R_TimeReport("console");
                }
 
@@ -803,8 +808,12 @@ void Host_Main(void)
                                wait = 1; // because we cast to int
 
                        time0 = Sys_DirtyTime();
-                       if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded)
+                       if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded) {
                                NetConn_SleepMicroseconds((int)wait);
+                               if (cls.state != ca_dedicated)
+                                       NetConn_ClientFrame(); // helps server browser get good ping values
+                               // TODO can we do the same for ServerFrame? Probably not.
+                       }
                        else
                                Sys_Sleep((int)wait);
                        delta = Sys_DirtyTime() - time0;
@@ -1016,6 +1025,7 @@ void Host_Main(void)
                        R_TimeReport("client");
 
                        CL_UpdateScreen();
+                       CL_MeshEntities_Reset();
                        R_TimeReport("render");
 
                        if (host_speeds.integer)
@@ -1030,10 +1040,8 @@ void Host_Main(void)
                        else
                                S_Update(&r_refdef.view.matrix);
 
-#ifdef CONFIG_CD
                        CDAudio_Update();
                        R_TimeReport("audio");
-#endif
 
                        // reset gathering of mouse input
                        in_mouse_x = in_mouse_y = 0;
@@ -1081,9 +1089,7 @@ void Host_StartVideo(void)
                // make sure we open sockets before opening video because the Windows Firewall "unblock?" dialog can screw up the graphics context on some graphics drivers
                NetConn_UpdateSockets();
                VID_Start();
-#ifdef CONFIG_CD
                CDAudio_Startup();
-#endif
        }
 }
 
@@ -1091,8 +1097,6 @@ char engineversion[128];
 
 qboolean sys_nostdout = false;
 
-extern qboolean host_stuffcmdsrun;
-
 static qfile_t *locksession_fh = NULL;
 static qboolean locksession_run = false;
 static void Host_InitSession(void)
@@ -1162,19 +1166,21 @@ static void Host_Init (void)
        int i;
        const char* os;
        char vabuf[1024];
+       qboolean dedicated_server = COM_CheckParm("-dedicated") || !cl_available;
+       cmd_state_t *cmd = &cmd_client;
 
        if (COM_CheckParm("-profilegameonly"))
                Sys_AllowProfiling(false);
 
-       // LordHavoc: quake never seeded the random number generator before... heh
+       // LadyHavoc: quake never seeded the random number generator before... heh
        if (COM_CheckParm("-benchmark"))
                srand(0); // predictable random sequence for -benchmark
        else
                srand((unsigned int)time(NULL));
 
        // FIXME: this is evil, but possibly temporary
-       // LordHavoc: doesn't seem very temporary...
-       // LordHavoc: made this a saved cvar
+       // LadyHavoc: doesn't seem very temporary...
+       // LadyHavoc: made this a saved cvar
 // COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers)
        if (COM_CheckParm("-developer"))
        {
@@ -1212,6 +1218,8 @@ static void Host_Init (void)
        // initialize console command/cvar/alias/command execution systems
        Cmd_Init();
 
+       Cmd_Init_Commands(dedicated_server);
+
        // initialize memory subsystem cvars/commands
        Memory_Init_Commands();
 
@@ -1221,7 +1229,6 @@ static void Host_Init (void)
        // initialize various cvars that could not be initialized earlier
        u8_Init();
        Curl_Init_Commands();
-       Cmd_Init_Commands();
        Sys_Init_Commands();
        COM_Init_Commands();
        FS_Init_Commands();
@@ -1270,9 +1277,13 @@ static void Host_Init (void)
        Host_ServerOptions();
 
        Thread_Init();
+       TaskQueue_Init();
 
        if (cls.state == ca_dedicated)
-               Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server (or disconnect all clients if running a server)");
+       {
+               cmd = &cmd_server;
+               Cmd_AddCommand(&cmd_server, "disconnect", CL_Disconnect_f, "disconnect from server (or disconnect all clients if running a server)");
+       }
        else
        {
                Con_DPrintf("Initializing client\n");
@@ -1286,9 +1297,7 @@ static void Host_Init (void)
                VID_Init();
                Render_Init();
                S_Init();
-#ifdef CONFIG_CD
                CDAudio_Init();
-#endif
                Key_Init();
                CL_Init();
        }
@@ -1305,14 +1314,14 @@ static void Host_Init (void)
                return;
        }
 
-       Host_AddConfigText();
-       Cbuf_Execute();
+       Host_AddConfigText(cmd);
+       Cbuf_Execute(cmd);
 
        // if stuffcmds wasn't run, then quake.rc is probably missing, use default
        if (!host_stuffcmdsrun)
        {
-               Cbuf_AddText("exec default.cfg\nexec " CONFIGFILENAME "\nexec autoexec.cfg\nstuffcmds\n");
-               Cbuf_Execute();
+               Cbuf_AddText(cmd, "exec default.cfg\nexec " CONFIGFILENAME "\nexec autoexec.cfg\nstuffcmds\n");
+               Cbuf_Execute(cmd);
        }
 
        // put up the loading image so the user doesn't stare at a black screen...
@@ -1331,8 +1340,8 @@ static void Host_Init (void)
        if (i && i + 1 < com_argc)
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
-               Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", com_argv[i + 1]));
-               Cbuf_Execute();
+               Cbuf_AddText(&cmd_client, va(vabuf, sizeof(vabuf), "timedemo %s\n", com_argv[i + 1]));
+               Cbuf_Execute(&cmd_client);
        }
 
        // check for special demo mode
@@ -1341,8 +1350,8 @@ static void Host_Init (void)
        if (i && i + 1 < com_argc)
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
-               Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\n", com_argv[i + 1]));
-               Cbuf_Execute();
+               Cbuf_AddText(&cmd_client, va(vabuf, sizeof(vabuf), "playdemo %s\n", com_argv[i + 1]));
+               Cbuf_Execute(&cmd_client);
        }
 
 // COMMANDLINEOPTION: Client: -capturedemo <demoname> captures a playdemo and quits
@@ -1350,23 +1359,23 @@ static void Host_Init (void)
        if (i && i + 1 < com_argc)
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
-               Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1]));
-               Cbuf_Execute();
+               Cbuf_AddText(&cmd_client, va(vabuf, sizeof(vabuf), "playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1]));
+               Cbuf_Execute(&cmd_client);
        }
 
        if (cls.state == ca_dedicated || COM_CheckParm("-listen"))
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
-               Cbuf_AddText("startmap_dm\n");
-               Cbuf_Execute();
+               Cbuf_AddText(&cmd_client, "startmap_dm\n");
+               Cbuf_Execute(&cmd_client);
        }
 
        if (!sv.active && !cls.demoplayback && !cls.connect_trying)
        {
 #ifdef CONFIG_MENU
-               Cbuf_AddText("togglemenu 1\n");
+               Cbuf_AddText(&cmd_client, "togglemenu 1\n");
 #endif
-               Cbuf_Execute();
+               Cbuf_Execute(&cmd_client);
        }
 
        Con_DPrint("========Initialized=========\n");
@@ -1430,9 +1439,7 @@ void Host_Shutdown(void)
 
        Host_SaveConfig();
 
-#ifdef CONFIG_CD
        CDAudio_Shutdown ();
-#endif
        S_Terminate ();
        Curl_Shutdown ();
        NetConn_Shutdown ();
@@ -1445,6 +1452,7 @@ void Host_Shutdown(void)
        }
 
        SV_StopThread();
+       TaskQueue_Shutdown();
        Thread_Shutdown();
        Cmd_Shutdown();
        Key_Shutdown();