Restart empty missions after the last disconnect and every five hours

Use connected player counts to protect loading players and spectators, and elapsed real time for idle restarts. Reuse native mission termination and cover restart timing, authority and lifecycle guards with targeted regressions.
This commit is contained in:
2026-10-14 13:56:56 +02:00
parent bf85f62dca
commit 0048527fe2
6 changed files with 164 additions and 24 deletions
+4 -2
View File
@@ -75,14 +75,16 @@ int main(){
if(fault==0){server=false;}if(fault==1){f.m.m_Phase=0;}if(fault==2){f.m.m_Phase=5;}
if(fault==3){f.m.m_StartedPlayers=true;}if(fault==4){game.players.connected[1]=&f.second;}if(fault==5){f.m.roster.lives.clear();}
f.exhaust();assert(f.m.m_ExhaustedInitialAdmissions.values.empty());}
// Empty server must retire a played round after the last reserved body expires.
// The inner survivor check retains its expiry behavior; the outer tick now
// handles empty-server restarts first (see test_empty_server_restart.py).
{Fixture f;f.m.m_StartedPlayers=true;f.m.roster.lives[1].UsedLife=true;
game.players.connected.clear();f.m.roster.survivor=true;
f.tick(900000);assert(f.m.Active()&&f.m.m_NoSurvivorsSince==-1);
f.m.roster.survivor=false;f.tick(901000);assert(f.m.m_NoSurvivorsSince==901000);
f.tick(930999);assert(f.m.Active());f.tick(931000);
assert(!f.m.Active()&&f.m.m_EndReason=="No surviving prisoners remain.");}
// A new empty round waits indefinitely; it must not restart in a loop.
// Empty, unplayed rounds do not trigger the inner no-survivor check.
// Their five-hour deadline belongs to the outer tick, tested separately.
{Fixture f;game.players.connected.clear();f.tick(0);f.tick(36000000);
assert(f.m.Active()&&f.m.m_NoSurvivorsSince==-1);}
// A valid reservation/recovered survivor cancels a pending empty-server loss.