using System.Linq;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
+using Content.Server.Administration.Managers;
using Content.Server.Chat.Managers;
using Content.Server.Database;
using Content.Server.GameTicking;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
+ [Dependency] private readonly IAdminManager _adminManager = default!;
private ISawmill _sawmill = default!;
private readonly Dictionary<NetUserId, TimeSpan> _temporaryBypasses = [];
ticker.PlayerGameStatuses.TryGetValue(userId, out var status) &&
status == PlayerGameStatus.JoinedGame;
var adminBypass = _cfg.GetCVar(CCVars.AdminBypassMaxPlayers) && adminData != null;
- if ((_plyMgr.PlayerCount >= _cfg.GetCVar(CCVars.SoftMaxPlayers) && !adminBypass) && !wasInGame)
+ var softPlayerCount = _plyMgr.PlayerCount;
+
+ if (!_cfg.GetCVar(CCVars.AdminsCountForMaxPlayers))
+ {
+ softPlayerCount -= _adminManager.ActiveAdmins.Count();
+ }
+
+ if ((softPlayerCount >= _cfg.GetCVar(CCVars.SoftMaxPlayers) && !adminBypass) && !wasInGame)
{
return (ConnectionDenyReason.Full, Loc.GetString("soft-player-cap-full"), null);
}
foreach (var whitelist in _whitelists)
{
- if (!IsValid(whitelist, _plyMgr.PlayerCount))
+ if (!IsValid(whitelist, softPlayerCount))
{
// Not valid for current player count.
continue;
public static readonly CVarDef<bool> AdminBypassMaxPlayers =
CVarDef.Create("admin.bypass_max_players", true, CVar.SERVERONLY);
+ /// <summary>
+ /// Determines whether admins count towards the total playercount when determining whether the server is over <see cref="SoftMaxPlayers"/>
+ /// Ideally this should be used in conjuction with <see cref="AdminBypassPlayers"/>.
+ /// This also applies to playercount limits in whitelist conditions
+ /// If false, then admins will not be considered when checking whether the playercount is already above the soft player cap
+ /// </summary>
+ public static readonly CVarDef<bool> AdminsCountForMaxPlayers =
+ CVarDef.Create("admin.admins_count_for_max_players", false, CVar.SERVERONLY);
+
/// <summary>
/// Determine if custom rank names are used.
/// If it is false, it'd use the actual rank name regardless of the individual's title.