--- a/rts/Net/GameServer.cpp +++ b/rts/Net/GameServer.cpp @@ -70,6 +70,7 @@ CONFIG(int, ServerSleepTime).defaultValue(5).description("Number of milliseconds to sleep per tick for the server thread. Lower values have marginally higher CPU load, while high values can introduce additional latency."); CONFIG(int, SpeedControl).defaultValue(1).minimumValue(1).maximumValue(2) .description("Sets how server adjusts speed according to player's load (CPU), 1: use average, 2: use highest"); +CONFIG(bool, WebbarRequireAllPlayers).defaultValue(false).description("Require every configured participant to finish loading before starting a private WebBAR match."); CONFIG(bool, AllowSpectatorJoin).defaultValue(true).dedicatedValue(false).description("allow any unauthenticated clients to join as spectator with any name, name will be prefixed with ~"); CONFIG(bool, WhiteListAdditionalPlayers).defaultValue(true); CONFIG(bool, ServerRecordDemos).defaultValue(false).dedicatedValue(true); @@ -2191,6 +2192,7 @@ void CGameServer::CheckForGameStart(bool forced) { assert(!gameHasStarted); + const bool requireAllPlayers = configHandler->GetBool("WebbarRequireAllPlayers"); bool allReady = true; // anyReady is needed for the case when *nodoby* is connected to the server yet, so in principle // everybody that is, is ready. Without that logic the game will start after XX seconds (see below) @@ -2200,6 +2202,11 @@ for (size_t a = static_cast(myGameSetup->numDemoPlayers); a < players.size(); a++) { if (players[a].isFromDemo) continue; + + if (requireAllPlayers && players[a].myState != GameParticipant::INGAME) { + allReady = false; + break; + } if (players[a].myState == GameParticipant::UNCONNECTED && serverStartTime + spring_secs(30) < spring_gettime()) { // autostart the game when 30 seconds have passed and everyone who managed to connect is ready @@ -2214,6 +2221,14 @@ } else { anyReady = true; } + } + + // Private rooms must not bypass readiness through timeout, force-start, or + // a participant disconnecting during the countdown. The room service owns + // a bounded loading deadline and cancellation. + if (requireAllPlayers && (!allReady || !anyReady)) { + readyTime = spring_notime; + return; } // msecs to wait until the game starts after all players are ready