]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/g_world.qc
Move assault winning condition function into the assault file
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / g_world.qc
index b49b2160ed0a2860f2d98b81d90c0f473760fed9..5fc7b9f99042cc71b31e82f02c84c5c7a7b80fb8 100644 (file)
@@ -563,7 +563,71 @@ void WeaponStats_Init();
 void WeaponStats_Shutdown();
 spawnfunc(worldspawn)
 {
-       float fd, l, j, n;
+       server_is_dedicated = boolean(stof(cvar_defstring("is_dedicated")));
+
+       {
+               bool wantrestart = false;
+
+               if (!server_is_dedicated)
+               {
+                       // force unloading of server pk3 files when starting a listen server
+                       // localcmd("\nfs_rescan\n"); // FIXME: does more harm than good, has unintended side effects. What we really want is to unload temporary pk3s only
+                       // restore csqc_progname too
+                       string expect = "csprogs.dat";
+                       wantrestart = cvar_string_normal("csqc_progname") != expect;
+                       cvar_set_normal("csqc_progname", expect);
+               }
+               else
+               {
+                       // Try to use versioned csprogs from pk3
+                       // Only ever use versioned csprogs.dat files on dedicated servers;
+                       // we need to reset csqc_progname on clients ourselves, and it's easier if the client's release name is constant
+                       string pk3csprogs = "csprogs-" WATERMARK ".dat";
+                       // This always works; fall back to it if a versioned csprogs.dat is suddenly missing
+                       string select = "csprogs.dat";
+                       if (fexists(pk3csprogs)) select = pk3csprogs;
+                       if (cvar_string_normal("csqc_progname") != select)
+                       {
+                               cvar_set_normal("csqc_progname", select);
+                               wantrestart = true;
+                       }
+                       // Check for updates on startup
+                       // We do it this way for atomicity so that connecting clients still match the server progs and don't disconnect
+                       int sentinel = fopen("progs.txt", FILE_READ);
+                       if (sentinel >= 0)
+                       {
+                               string switchversion = fgets(sentinel);
+                               fclose(sentinel);
+                               if (switchversion != "" && switchversion != WATERMARK)
+                               {
+                                       LOG_INFOF("Switching progs: " WATERMARK " -> %s\n", switchversion);
+                                       // if it doesn't exist, assume either:
+                                       //   a) the current program was overwritten
+                                       //   b) this is a client only update
+                                       string newprogs = sprintf("progs-%s.dat", switchversion);
+                                       if (fexists(newprogs))
+                                       {
+                                               cvar_set_normal("sv_progs", newprogs);
+                                               wantrestart = true;
+                                       }
+                                       string newcsprogs = sprintf("csprogs-%s.dat", switchversion);
+                                       if (fexists(newcsprogs))
+                                       {
+                                               cvar_set_normal("csqc_progname", newcsprogs);
+                                               wantrestart = true;
+                                       }
+                               }
+                       }
+               }
+               if (wantrestart)
+               {
+                       LOG_INFOF("Restart requested\n");
+                       changelevel(mapname);
+                       // let initialization continue, shutdown depends on it
+               }
+       }
+
+       float fd, l;
        string s;
 
        cvar = cvar_normal;
@@ -586,8 +650,6 @@ spawnfunc(worldspawn)
                ++maxclients;
        }
 
-       server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? true : false);
-
        // needs to be done so early because of the constants they create
        static_init();
 
@@ -783,31 +845,34 @@ spawnfunc(worldspawn)
        localcmd("\n_sv_hook_gamestart ", GetGametype(), "\n");
 
        // fill sv_curl_serverpackages from .serverpackage files
-       if(autocvar_sv_curl_serverpackages_auto)
+       if (autocvar_sv_curl_serverpackages_auto)
        {
-               s = "";
-               n = tokenize_console(cvar_string("sv_curl_serverpackages"));
-               for(int i = 0; i < n; ++i)
-                       if(substring(argv(i), -18, -1) != "-serverpackage.txt")
-                       if(substring(argv(i), -14, -1) != ".serverpackage") // OLD legacy
-                               s = strcat(s, " ", argv(i));
-               fd = search_begin("*-serverpackage.txt", true, false);
-               if(fd >= 0)
-               {
-                       j = search_getsize(fd);
-                       for(int i = 0; i < j; ++i)
-                               s = strcat(s, " ", search_getfilename(fd, i));
-                       search_end(fd);
-               }
-               fd = search_begin("*.serverpackage", true, false);
-               if(fd >= 0)
+               s = "csprogs-" WATERMARK ".txt";
+               // remove automatically managed files from the list to prevent duplicates
+               for (int i = 0, n = tokenize_console(cvar_string("sv_curl_serverpackages")); i < n; ++i)
                {
-                       j = search_getsize(fd);
-                       for(int i = 0; i < j; ++i)
-                               s = strcat(s, " ", search_getfilename(fd, i));
-                       search_end(fd);
+                       string pkg = argv(i);
+                       if (startsWith(pkg, "csprogs-")) continue;
+                       if (endsWith(pkg, "-serverpackage.txt")) continue;
+                       if (endsWith(pkg, ".serverpackage")) continue;  // OLD legacy
+                       s = cons(s, pkg);
                }
-               cvar_set("sv_curl_serverpackages", substring(s, 1, -1));
+               // add automatically managed files to the list
+               #define X(match) MACRO_BEGIN { \
+                       fd = search_begin(match, true, false); \
+                       if (fd >= 0) \
+                       { \
+                               for (int i = 0, j = search_getsize(fd); i < j; ++i) \
+                               { \
+                                       s = cons(s, search_getfilename(fd, i)); \
+                               } \
+                               search_end(fd); \
+                       } \
+               } MACRO_END
+               X("*-serverpackage.txt");
+               X("*.serverpackage");
+               #undef X
+               cvar_set("sv_curl_serverpackages", s);
        }
 
        // MOD AUTHORS: change this, and possibly remove a few of the blocks below to ignore certain changes
@@ -1583,51 +1648,6 @@ void ClearWinners()
        FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(it.winning = 0));
 }
 
-// Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives)
-// they win. Otherwise the defending team wins once the timelimit passes.
-void assault_new_round();
-float WinningCondition_Assault()
-{SELFPARAM();
-       float status;
-
-       WinningConditionHelper(); // set worldstatus
-
-       status = WINNING_NO;
-       // as the timelimit has not yet passed just assume the defending team will win
-       if(assault_attacker_team == NUM_TEAM_1)
-       {
-               SetWinners(team, NUM_TEAM_2);
-       }
-       else
-       {
-               SetWinners(team, NUM_TEAM_1);
-       }
-
-       entity ent;
-       ent = find(world, classname, "target_assault_roundend");
-       if(ent)
-       {
-               if(ent.winning) // round end has been triggered by attacking team
-               {
-                       bprint("ASSAULT: round completed...\n");
-                       SetWinners(team, assault_attacker_team);
-
-                       TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 666 - TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 0));
-
-                       if(ent.cnt == 1 || autocvar_g_campaign) // this was the second round
-                       {
-                               status = WINNING_YES;
-                       }
-                       else
-                       {
-                               WITH(entity, self, ent, assault_new_round());
-                       }
-               }
-       }
-
-       return status;
-}
-
 void ShuffleMaplist()
 {
        cvar_set("g_maplist", shufflewords(autocvar_g_maplist));