]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
server: fix the save command's checks for multiplayer/dedicated
authorbones_was_here <bones_was_here@xonotic.au>
Sun, 25 Aug 2024 10:17:29 +0000 (20:17 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Wed, 28 Aug 2024 13:11:02 +0000 (23:11 +1000)
Also makes the save and load messages nicer.

Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
cl_main.c
host.c
host.h
sv_ccmds.c
sv_save.c

index 1792141051135167fa2b7923d2b43030c0eebee7..5ca74b6436f5c705a6530822e256bba9d02373e1 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -620,10 +620,6 @@ static void CL_EstablishConnection_Local(void)
                CL_EstablishConnection("local:1", -2);
 }
 
-static qbool CL_Intermission(void)
-{
-       return cl.intermission;
-}
 
 /*
 ==============
@@ -3149,7 +3145,6 @@ void CL_Init (void)
 
                host.hook.ConnectLocal = CL_EstablishConnection_Local;
                host.hook.Disconnect = CL_DisconnectEx;
-               host.hook.CL_Intermission = CL_Intermission;
                host.hook.ToggleMenu = CL_ToggleMenu_Hook;
        }
 }
diff --git a/host.c b/host.c
index ab0b077916725ed7c7157dbddb2ba711fcbb8f4d..b92f11b3ee0dcb219e3fee80b87a599de83dca9f 100644 (file)
--- a/host.c
+++ b/host.c
@@ -385,7 +385,6 @@ void Host_Init (void)
        host.hook.ConnectLocal = NULL;
        host.hook.Disconnect = NULL;
        host.hook.ToggleMenu = NULL;
-       host.hook.CL_Intermission = NULL;
        host.hook.SV_Shutdown = NULL;
 
        host.state = host_init;
diff --git a/host.h b/host.h
index e72d75a2183426a5ecd69756bc1794f1b6c75d4f..def3d0a24c018ed3dd0c1e4746f6f76c888bd0ef 100644 (file)
--- a/host.h
+++ b/host.h
@@ -46,7 +46,6 @@ typedef struct host_static_s
                void (*ConnectLocal)(void);
                void (*Disconnect)(qbool, const char *, ... );
                void (*ToggleMenu)(void);
-               qbool (*CL_Intermission)(void); // Quake compatibility
                void (*CL_SendCvar)(struct cmd_state_s *);
                void (*SV_SendCvar)(struct cmd_state_s *);
                void (*SV_Shutdown)(void);
index 64b3d1977abe8a4ee628d3382f1a031e1cedd354..836181f227b930728ba5ce3b10d61dcb9a82d168 100644 (file)
@@ -1655,8 +1655,8 @@ void SV_InitOperatorCommands(void)
        Cmd_AddCommand(CF_SERVER | CF_SERVER_FROM_CLIENT, "pause", SV_Pause_f, "pause the game (if the server allows pausing)");
        Cmd_AddCommand(CF_SHARED, "kick", SV_Kick_f, "kick a player off the server by number or name");
        Cmd_AddCommand(CF_SHARED | CF_SERVER_FROM_CLIENT, "ping", SV_Ping_f, "print ping times of all players on the server");
-       Cmd_AddCommand(CF_SHARED, "load", SV_Loadgame_f, "load a saved game file");
-       Cmd_AddCommand(CF_SHARED, "save", SV_Savegame_f, "save the game to a file");
+       Cmd_AddCommand(CF_SERVER, "load", SV_Loadgame_f, "load a saved game file");
+       Cmd_AddCommand(CF_SERVER, "save", SV_Savegame_f, "save the game to a file");
        Cmd_AddCommand(CF_SHARED, "viewmodel", SV_Viewmodel_f, "change model of viewthing entity in current level");
        Cmd_AddCommand(CF_SHARED, "viewframe", SV_Viewframe_f, "change animation frame of viewthing entity in current level");
        Cmd_AddCommand(CF_SHARED, "viewnext", SV_Viewnext_f, "change to next animation frame of viewthing entity in current level");
index 5901b6dc66de7f1c08a8b0554c9ac0a585b169f1..653292a066067e3ac2c3f7bd78eb9c15382dde82 100644 (file)
--- a/sv_save.c
+++ b/sv_save.c
@@ -53,7 +53,7 @@ void SV_Savegame_to(prvm_prog_t *prog, const char *name)
        f = FS_OpenRealFile(name, "wb", false);
        if (!f)
        {
-               Con_Print("ERROR: couldn't open.\n");
+               Con_Print(CON_ERROR "ERROR: couldn't open.\n");
                return;
        }
 
@@ -180,30 +180,6 @@ void SV_Savegame_to(prvm_prog_t *prog, const char *name)
        Con_Print("done.\n");
 }
 
-static qbool SV_CanSave(void)
-{
-       prvm_prog_t *prog = SVVM_prog;
-       if(SV_IsLocalServer() == 1)
-       {
-               // singleplayer checks
-               // FIXME: This only checks if the first player is dead?
-               if ((svs.clients[0].active && PRVM_serveredictfloat(svs.clients[0].edict, deadflag)))
-               {
-                       Con_Print("Can't savegame with a dead player\n");
-                       return false;
-               }
-
-               if(host.hook.CL_Intermission && host.hook.CL_Intermission())
-               {
-                       Con_Print("Can't save in intermission.\n");
-                       return false;
-               }
-       }
-       else
-               Con_Print(CON_WARN "Warning: saving a multiplayer game may have strange results when restored (to properly resume, all players must join in the same player slots and then the game can be reloaded).\n");
-       return true;
-}
-
 /*
 ===============
 SV_Savegame_f
@@ -216,13 +192,10 @@ void SV_Savegame_f(cmd_state_t *cmd)
 
        if (!sv.active)
        {
-               Con_Print("Can't save - no server running.\n");
+               Con_Print(CON_ERROR "Can't save - no server running.\n");
                return;
        }
 
-       if(!SV_CanSave())
-               return;
-
        if (Cmd_Argc(cmd) != 2)
        {
                Con_Print("save <savename> : save a game\n");
@@ -231,10 +204,28 @@ void SV_Savegame_f(cmd_state_t *cmd)
 
        if (strstr(Cmd_Argv(cmd, 1), ".."))
        {
-               Con_Print("Relative pathnames are not allowed.\n");
+               Con_Print(CON_ERROR "Relative pathnames are not allowed.\n");
+               return;
+       }
+
+       for (int i = 0; i < svs.maxclients; ++i)
+               if (svs.clients[i].active && PRVM_serveredictfloat(svs.clients[i].edict, deadflag))
+               {
+                       Con_Print(CON_ERROR "Can't savegame with a dead player\n");
+                       return;
+               }
+
+       // bones_was_here: intermission_running isn't declared in dpdefs, but it's used by
+       // id1 Quake, all Quake mods (afaict), Nexuiz and Xonotic.
+       if (PRVM_serverglobalfloat(intermission_running))
+       {
+               Con_Print(CON_ERROR "Can't save in intermission.\n");
                return;
        }
 
+       if (SV_IsLocalServer() != 1)
+               Con_Print(CON_WARN "Warning: saving a multiplayer game may have strange results when restored (to properly resume, all players must join in the same player slots and then the game can be reloaded).\n");
+
        dp_strlcpy (name, Cmd_Argv(cmd, 1), sizeof (name));
        FS_DefaultExtension (name, ".sav", sizeof (name));
 
@@ -285,7 +276,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
        t = text = (char *)FS_LoadFile (filename, tempmempool, false, NULL);
        if (!text)
        {
-               Con_Print("ERROR: couldn't open.\n");
+               Con_Print(CON_ERROR "ERROR: couldn't open.\n");
                return;
        }
 
@@ -298,7 +289,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
        if (version != SAVEGAME_VERSION)
        {
                Mem_Free(text);
-               Con_Printf("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION);
+               Con_Printf(CON_ERROR "Savegame is version %i, not %i\n", version, SAVEGAME_VERSION);
                return;
        }
 
@@ -340,7 +331,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
        if (!sv.active)
        {
                Mem_Free(text);
-               Con_Print("Couldn't load map\n");
+               Con_Printf(CON_ERROR "Couldn't load map \"%s\"\n", mapname);
                return;
        }
        sv.paused = true;               // pause until all clients connect
@@ -407,7 +398,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
                if (strcmp(com_token,"{"))
                {
                        Mem_Free(text);
-                       Host_Error ("First token isn't a brace");
+                       Host_Error ("%s: first token isn't a brace", __func__);
                }
 
                if (entnum == -1)
@@ -427,7 +418,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
                        if (entnum >= MAX_EDICTS)
                        {
                                Mem_Free(text);
-                               Host_Error("Host_PerformLoadGame: too many edicts in save file (reached MAX_EDICTS %i)", MAX_EDICTS);
+                               Host_Error("%s: too many edicts in save file (reached MAX_EDICTS %i)", __func__, MAX_EDICTS);
                        }
                        while (entnum >= prog->max_edicts)
                                PRVM_MEM_IncreaseEdicts(prog);
@@ -487,7 +478,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
                                        if (i >= 0 && i < MAX_LIGHTSTYLES)
                                                dp_strlcpy(sv.lightstyles[i], com_token, sizeof(sv.lightstyles[i]));
                                        else
-                                               Con_Printf("unsupported lightstyle %i \"%s\"\n", i, com_token);
+                                               Con_Printf(CON_WARN "unsupported lightstyle %i \"%s\"\n", i, com_token);
                                }
                                else if (!strcmp(com_token, "sv.model_precache"))
                                {
@@ -500,7 +491,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
                                                sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, sv.model_precache[i][0] == '*' ? sv.worldname : NULL);
                                        }
                                        else
-                                               Con_Printf("unsupported model %i \"%s\"\n", i, com_token);
+                                               Con_Printf(CON_WARN "unsupported model %i \"%s\"\n", i, com_token);
                                }
                                else if (!strcmp(com_token, "sv.sound_precache"))
                                {
@@ -510,7 +501,7 @@ void SV_Loadgame_f(cmd_state_t *cmd)
                                        if (i >= 0 && i < MAX_SOUNDS)
                                                dp_strlcpy(sv.sound_precache[i], com_token, sizeof(sv.sound_precache[i]));
                                        else
-                                               Con_Printf("unsupported sound %i \"%s\"\n", i, com_token);
+                                               Con_Printf(CON_WARN "unsupported sound %i \"%s\"\n", i, com_token);
                                }
                                else if (!strcmp(com_token, "sv.buffer"))
                                {
@@ -526,15 +517,15 @@ void SV_Loadgame_f(cmd_state_t *cmd)
                                                                Con_Printf(CON_ERROR "failed to create stringbuffer %i\n", i);
                                                }
                                                else
-                                                       Con_Printf("unsupported stringbuffer index %i \"%s\"\n", i, com_token);
+                                                       Con_Printf(CON_WARN "unsupported stringbuffer index %i \"%s\"\n", i, com_token);
                                        }
                                        else
-                                               Con_Printf("unexpected end of line when parsing sv.buffer (expected buffer index)\n");
+                                               Con_Printf(CON_WARN "unexpected end of line when parsing sv.buffer (expected buffer index)\n");
                                }
                                else if (!strcmp(com_token, "sv.bufstr"))
                                {
                                        if (!COM_ParseToken_Simple(&t, false, false, true))
-                                               Con_Printf("unexpected end of line when parsing sv.bufstr\n");
+                                               Con_Printf(CON_WARN "unexpected end of line when parsing sv.bufstr\n");
                                        else
                                        {
                                                i = atoi(com_token);
@@ -547,10 +538,10 @@ void SV_Loadgame_f(cmd_state_t *cmd)
                                                                if (COM_ParseToken_Simple(&t, false, false, true))
                                                                        BufStr_Set(prog, stringbuffer, k, com_token);
                                                                else
-                                                                       Con_Printf("unexpected end of line when parsing sv.bufstr (expected string)\n");
+                                                                       Con_Printf(CON_WARN "unexpected end of line when parsing sv.bufstr (expected string)\n");
                                                        }
                                                        else
-                                                               Con_Printf("unexpected end of line when parsing sv.bufstr (expected strindex)\n");
+                                                               Con_Printf(CON_WARN "unexpected end of line when parsing sv.bufstr (expected strindex)\n");
                                                }
                                                else
                                                        Con_Printf(CON_ERROR "failed to create stringbuffer %i \"%s\"\n", i, com_token);