diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs index a2b243fc35..6222299d9b 100644 --- a/Content.Server/Connection/ConnectionManager.cs +++ b/Content.Server/Connection/ConnectionManager.cs @@ -1,13 +1,13 @@ using System; using System.Collections.Immutable; using System.Threading.Tasks; -using Content.Server.Administration.Managers; using Content.Server.Database; +using Content.Server.GameTicking; using Content.Server.Preferences.Managers; -using Content.Shared; using Content.Shared.CCVar; using Robust.Server.Player; using Robust.Shared.Configuration; +using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Network; @@ -76,9 +76,10 @@ The ban reason is: ""{ban.Reason}"" } var adminData = await _dbManager.GetAdminDataForAsync(e.UserId); - if (_plyMgr.PlayerCount >= _cfg.GetCVar(CCVars.SoftMaxPlayers) && adminData is null) + var wasInGame = EntitySystem.TryGet(out var ticker) && ticker.PlayersInGame.Contains(userId); + if ((_plyMgr.PlayerCount >= _cfg.GetCVar(CCVars.SoftMaxPlayers) && adminData is null) && !wasInGame ) { - e.Deny("The server is full!"); + e.Deny(Loc.GetString("soft-player-cap-full")); return; } diff --git a/Content.Server/GameTicking/GameTicker.Lobby.cs b/Content.Server/GameTicking/GameTicker.Lobby.cs index 369495d9c3..0f7faa4beb 100644 --- a/Content.Server/GameTicking/GameTicker.Lobby.cs +++ b/Content.Server/GameTicking/GameTicker.Lobby.cs @@ -16,6 +16,8 @@ namespace Content.Server.GameTicking [ViewVariables] private readonly Dictionary _playersInLobby = new(); + [ViewVariables] private readonly HashSet _playersInGame = new(); + [ViewVariables] private TimeSpan _roundStartTime; @@ -29,6 +31,7 @@ namespace Content.Server.GameTicking private bool _roundStartCountdownHasNotStartedYetDueToNoPlayers; public IReadOnlyDictionary PlayersInLobby => _playersInLobby; + public IReadOnlySet PlayersInGame => _playersInGame; private void UpdateInfoText() { diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs index 63e51b9845..3fcfcb2648 100644 --- a/Content.Server/GameTicking/GameTicker.Player.cs +++ b/Content.Server/GameTicking/GameTicker.Player.cs @@ -134,12 +134,15 @@ namespace Content.Server.GameTicking if (_playersInLobby.ContainsKey(session)) _playersInLobby.Remove(session); + _playersInGame.Add(session.UserId); + RaiseNetworkEvent(new TickerJoinGameEvent(), session.ConnectedClient); } private void PlayerJoinLobby(IPlayerSession session) { _playersInLobby[session] = LobbyPlayerStatus.NotReady; + _playersInGame.Remove(session.UserId); var client = session.ConnectedClient; RaiseNetworkEvent(new TickerJoinLobbyEvent(), client); diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 137b193237..a293ea588c 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -429,7 +429,7 @@ namespace Content.Server.GameTicking } // This ordering mechanism isn't great (no ordering of minds) but functions var listOfPlayerInfoFinal = listOfPlayerInfo.OrderBy(pi => pi.PlayerOOCName).ToArray(); - + _playersInGame.Clear(); RaiseNetworkEvent(new RoundEndMessageEvent(gamemodeTitle, roundEndText, roundDuration, listOfPlayerInfoFinal.Length, listOfPlayerInfoFinal)); } diff --git a/Resources/Locale/en-US/whitelist.ftl b/Resources/Locale/en-US/connection-messages.ftl similarity index 92% rename from Resources/Locale/en-US/whitelist.ftl rename to Resources/Locale/en-US/connection-messages.ftl index 7cac1dff38..a5cd4c695e 100644 --- a/Resources/Locale/en-US/whitelist.ftl +++ b/Resources/Locale/en-US/connection-messages.ftl @@ -8,3 +8,5 @@ command-whitelistremove-help = whitelistremove command-kicknonwhitelisted-description = Kicks all non-whitelisted players from the server. command-kicknonwhitelisted-help = kicknonwhitelisted + +soft-player-cap-full = The server is full!