using System.Linq;
using System.Numerics;
+using Content.Client.Gameplay;
using Content.Client.Stylesheets;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using JetBrains.Annotations;
using Robust.Client.AutoGenerated;
using Robust.Client.Console;
+using Robust.Client.State;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IEntityNetworkManager _entNetManager = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
+ [Dependency] private readonly IStateManager _state = default!;
private VotingSystem _votingSystem;
VoteTypeButton.AddItem(Loc.GetString(option.Name), (int)voteType);
}
+ _state.OnStateChanged += OnStateChanged;
VoteTypeButton.OnItemSelected += VoteTypeSelected;
CreateButton.OnPressed += CreatePressed;
FollowButton.OnPressed += FollowSelected;
UpdateVoteTimeout();
}
+ private void OnStateChanged(StateChangedEventArgs obj)
+ {
+ if (obj.NewState is not GameplayState)
+ return;
+
+ Close();
+ }
+
private void CanCallVoteChanged(bool obj)
{
if (!obj)
private void OnVotePlayerListResponseEvent(VotePlayerListResponseEvent msg)
{
- if (!_ghostSystem.IsGhost)
- {
- return;
- }
-
VotePlayerListResponse?.Invoke(msg);
}
private VotingSystem? _votingSystem;
private RoleSystem? _roleSystem;
+ private GameTicker? _gameTicker;
private static readonly Dictionary<StandardVoteType, CVarDef<bool>> _voteTypesToEnableCVars = new()
{
default:
throw new ArgumentOutOfRangeException(nameof(voteType), voteType, null);
}
- var ticker = _entityManager.EntitySysManager.GetEntitySystem<GameTicker>();
- ticker.UpdateInfoText();
+ _gameTicker = _entityManager.EntitySysManager.GetEntitySystem<GameTicker>();
+ _gameTicker.UpdateInfoText();
if (timeoutVote)
TimeoutStandardVote(voteType);
}
return;
}
+
+
+ var voterEligibility = _cfg.GetCVar(CCVars.VotekickVoterGhostRequirement) ? VoterEligibility.GhostMinimumPlaytime : VoterEligibility.MinimumPlaytime;
+ if (_cfg.GetCVar(CCVars.VotekickIgnoreGhostReqInLobby) && _gameTicker!.RunLevel == GameRunLevel.PreRoundLobby)
+ voterEligibility = VoterEligibility.MinimumPlaytime;
+
var eligibleVoterNumberRequirement = _cfg.GetCVar(CCVars.VotekickEligibleNumberRequirement);
- var eligibleVoterNumber = _cfg.GetCVar(CCVars.VotekickVoterGhostRequirement) ? CalculateEligibleVoterNumber(VoterEligibility.GhostMinimumPlaytime) : CalculateEligibleVoterNumber(VoterEligibility.MinimumPlaytime);
+ var eligibleVoterNumber = CalculateEligibleVoterNumber(voterEligibility);
string target = args[0];
string reason = args[1];
},
Duration = TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.VotekickTimer)),
InitiatorTimeout = TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.VotekickTimeout)),
- VoterEligibility = _cfg.GetCVar(CCVars.VotekickVoterGhostRequirement) ? VoterEligibility.GhostMinimumPlaytime : VoterEligibility.MinimumPlaytime,
+ VoterEligibility = voterEligibility,
DisplayVotes = false,
TargetEntity = targetNetEntity
};
using Content.Server.Administration.Managers;
using Content.Server.Database;
+using Content.Server.GameTicking;
using Content.Server.Ghost;
using Content.Server.Roles.Jobs;
using Content.Shared.CCVar;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly JobSystem _jobs = default!;
+ [Dependency] private readonly GameTicker _gameTicker = default!;
public override void Initialize()
{
private async void OnVotePlayerListRequestEvent(VotePlayerListRequestEvent msg, EntitySessionEventArgs args)
{
- if (args.SenderSession.AttachedEntity is not { Valid: true } entity
- || !await CheckVotekickInitEligibility(args.SenderSession))
+ if (!await CheckVotekickInitEligibility(args.SenderSession))
{
var deniedResponse = new VotePlayerListResponseEvent(new (NetUserId, NetEntity, string)[0], true);
RaiseNetworkEvent(deniedResponse, args.SenderSession.Channel);
foreach (var player in _playerManager.Sessions)
{
- if (player.AttachedEntity is not { Valid: true } attached)
- continue;
-
- if (attached == entity) continue;
+ if (args.SenderSession == player) continue;
if (_adminManager.IsAdmin(player, false)) continue;
- var playerName = GetPlayerVoteListName(attached);
- var netEntity = GetNetEntity(attached);
-
- players.Add((player.UserId, netEntity, playerName));
+ if (player.AttachedEntity is not { Valid: true } attached)
+ {
+ var playerName = player.Name;
+ var netEntity = NetEntity.Invalid;
+ players.Add((player.UserId, netEntity, playerName));
+ }
+ else
+ {
+ var playerName = GetPlayerVoteListName(attached);
+ var netEntity = GetNetEntity(attached);
+
+ players.Add((player.UserId, netEntity, playerName));
+ }
}
var response = new VotePlayerListResponseEvent(players.ToArray(), false);
if (initiator.AttachedEntity != null && _adminManager.IsAdmin(initiator.AttachedEntity.Value, false))
return true;
- if (_cfg.GetCVar(CCVars.VotekickInitiatorGhostRequirement))
+ // If cvar enabled, skip the ghost requirement in the preround lobby
+ if (!_cfg.GetCVar(CCVars.VotekickIgnoreGhostReqInLobby) || (_cfg.GetCVar(CCVars.VotekickIgnoreGhostReqInLobby) && _gameTicker.RunLevel != GameRunLevel.PreRoundLobby))
{
- // Must be ghost
- if (!TryComp(initiator.AttachedEntity, out GhostComponent? ghostComp))
- return false;
-
- // Must have been dead for x seconds
- if ((int)_gameTiming.RealTime.Subtract(ghostComp.TimeOfDeath).TotalSeconds < _cfg.GetCVar(CCVars.VotekickEligibleVoterDeathtime))
- return false;
+ if (_cfg.GetCVar(CCVars.VotekickInitiatorGhostRequirement))
+ {
+ // Must be ghost
+ if (!TryComp(initiator.AttachedEntity, out GhostComponent? ghostComp))
+ return false;
+
+ // Must have been dead for x seconds
+ if ((int)_gameTiming.RealTime.Subtract(ghostComp.TimeOfDeath).TotalSeconds < _cfg.GetCVar(CCVars.VotekickEligibleVoterDeathtime))
+ return false;
+ }
}
// Must be whitelisted
public static readonly CVarDef<int> VotekickBanDuration =
CVarDef.Create("votekick.ban_duration", 180, CVar.SERVERONLY);
+ /// <summary>
+ /// Whether the ghost requirement settings for votekicks should be ignored for the lobby.
+ /// </summary>
+ public static readonly CVarDef<bool> VotekickIgnoreGhostReqInLobby =
+ CVarDef.Create("votekick.ignore_ghost_req_in_lobby", true, CVar.SERVERONLY);
+
/*
* BAN
*/