Add variables to prevent voting of various kinds (#5361)
* Add a way to disable voting for maximum authoritarianism * Allow disabling specific vote types via cvars * Migrate standard-vote-to-cvar dictionary to being static
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Voting;
|
||||
using JetBrains.Annotations;
|
||||
@@ -104,8 +105,15 @@ namespace Content.Client.Voting.UI
|
||||
|
||||
if (!isAvailable)
|
||||
{
|
||||
var remaining = timeout - _gameTiming.RealTime;
|
||||
VoteTypeTimeoutLabel.Text = Loc.GetString("ui-vote-type-timeout", ("remaining", remaining.ToString("mm\\:ss")));
|
||||
if (timeout == TimeSpan.Zero)
|
||||
{
|
||||
VoteTypeTimeoutLabel.Text = Loc.GetString("ui-vote-type-not-available");
|
||||
}
|
||||
else
|
||||
{
|
||||
var remaining = timeout - _gameTiming.RealTime;
|
||||
VoteTypeTimeoutLabel.Text = Loc.GetString("ui-vote-type-timeout", ("remaining", remaining.ToString("mm\\:ss")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,8 @@ namespace Content.Client.Voting
|
||||
_standardVoteTimeouts.Clear();
|
||||
foreach (var (type, time) in message.VotesUnavailable)
|
||||
{
|
||||
_standardVoteTimeouts.Add(type, _gameTiming.RealServerToLocal(time));
|
||||
var fixedTime = (time == TimeSpan.Zero) ? time : _gameTiming.RealServerToLocal(time);
|
||||
_standardVoteTimeouts.Add(type, fixedTime);
|
||||
}
|
||||
|
||||
CanCallStandardVotesChanged?.Invoke();
|
||||
|
||||
@@ -7,6 +7,7 @@ using Content.Server.RoundEnd;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Voting;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
@@ -16,6 +17,13 @@ namespace Content.Server.Voting.Managers
|
||||
{
|
||||
public sealed partial class VoteManager
|
||||
{
|
||||
private static readonly Dictionary<StandardVoteType, CVarDef<bool>> _voteTypesToEnableCVars = new()
|
||||
{
|
||||
{StandardVoteType.Restart, CCVars.VoteRestartEnabled},
|
||||
{StandardVoteType.Preset, CCVars.VotePresetEnabled},
|
||||
{StandardVoteType.Map, CCVars.VoteMapEnabled},
|
||||
};
|
||||
|
||||
public void CreateStandardVote(IPlayerSession? initiator, StandardVoteType voteType)
|
||||
{
|
||||
switch (voteType)
|
||||
|
||||
@@ -10,6 +10,7 @@ using Content.Server.Afk;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Maps;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Voting;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
@@ -45,6 +46,7 @@ namespace Content.Server.Voting.Managers
|
||||
private readonly Dictionary<StandardVoteType, TimeSpan> _standardVoteTimeout = new();
|
||||
private readonly Dictionary<NetUserId, TimeSpan> _voteTimeout = new();
|
||||
private readonly HashSet<IPlayerSession> _playerCanCallVoteDirty = new();
|
||||
private readonly StandardVoteType[] _standardVoteTypeValues = Enum.GetValues<StandardVoteType>();
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
@@ -53,6 +55,17 @@ namespace Content.Server.Voting.Managers
|
||||
|
||||
_playerManager.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
|
||||
_adminMgr.OnPermsChanged += AdminPermsChanged;
|
||||
|
||||
_cfg.OnValueChanged(CCVars.VoteEnabled, value => {
|
||||
DirtyCanCallVoteAll();
|
||||
});
|
||||
|
||||
foreach (var kvp in _voteTypesToEnableCVars)
|
||||
{
|
||||
_cfg.OnValueChanged(kvp.Value, value => {
|
||||
DirtyCanCallVoteAll();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void AdminPermsChanged(AdminPermsChangedEventArgs obj)
|
||||
@@ -262,9 +275,21 @@ namespace Content.Server.Voting.Managers
|
||||
msg.CanCall = CanCallVote(player, null, out var isAdmin, out var timeSpan);
|
||||
msg.WhenCanCallVote = timeSpan;
|
||||
|
||||
msg.VotesUnavailable = isAdmin
|
||||
? Array.Empty<(StandardVoteType, TimeSpan)>()
|
||||
: _standardVoteTimeout.Select(kv => (kv.Key, kv.Value)).ToArray();
|
||||
if (isAdmin)
|
||||
{
|
||||
msg.VotesUnavailable = Array.Empty<(StandardVoteType, TimeSpan)>();
|
||||
}
|
||||
else
|
||||
{
|
||||
var votesUnavailable = new List<(StandardVoteType, TimeSpan)>();
|
||||
foreach (var v in _standardVoteTypeValues)
|
||||
{
|
||||
if (CanCallVote(player, v, out var _isAdmin, out var typeTimeSpan))
|
||||
continue;
|
||||
votesUnavailable.Add((v, typeTimeSpan));
|
||||
}
|
||||
msg.VotesUnavailable = votesUnavailable.ToArray();
|
||||
}
|
||||
|
||||
_netManager.ServerSendMessage(msg, player.ConnectedClient);
|
||||
}
|
||||
@@ -285,13 +310,20 @@ namespace Content.Server.Voting.Managers
|
||||
return true;
|
||||
}
|
||||
|
||||
// If voting is disabled, block votes.
|
||||
if (!_cfg.GetCVar(CCVars.VoteEnabled))
|
||||
return false;
|
||||
// Specific standard vote types can be disabled with cvars.
|
||||
if ((voteType != null) && _voteTypesToEnableCVars.TryGetValue(voteType.Value, out var cvar) && !_cfg.GetCVar(cvar))
|
||||
return false;
|
||||
|
||||
// Cannot start vote if vote is already active (as non-admin).
|
||||
if (_votes.Count != 0)
|
||||
return false;
|
||||
|
||||
// Standard vote on timeout, no calling.
|
||||
// Ghosts I understand you're dead but stop spamming the restart vote bloody hell.
|
||||
if (voteType != null && _standardVoteTimeout.ContainsKey(voteType.Value))
|
||||
if (voteType != null && _standardVoteTimeout.TryGetValue(voteType.Value, out timeSpan))
|
||||
return false;
|
||||
|
||||
return !_voteTimeout.TryGetValue(initiator.UserId, out timeSpan);
|
||||
|
||||
@@ -431,6 +431,30 @@ namespace Content.Shared.CCVar
|
||||
* VOTE
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Allows enabling/disabling player-started votes for ultimate authority
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VoteEnabled =
|
||||
CVarDef.Create("vote.enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// See vote.enabled, but specific to restart votes
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VoteRestartEnabled =
|
||||
CVarDef.Create("vote.restart_enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// See vote.enabled, but specific to preset votes
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotePresetEnabled =
|
||||
CVarDef.Create("vote.preset_enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// See vote.enabled, but specific to map votes
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VoteMapEnabled =
|
||||
CVarDef.Create("vote.map_enabled", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// The required ratio of the server that must agree for a restart round vote to go through.
|
||||
/// </summary>
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Content.Shared.Voting
|
||||
public TimeSpan WhenCanCallVote;
|
||||
|
||||
// Which standard votes are currently unavailable, and when will they become available.
|
||||
// The whenAvailable can be null if the reason is something not timeout related.
|
||||
public (StandardVoteType type, TimeSpan whenAvailable)[] VotesUnavailable = default!;
|
||||
|
||||
// It's possible to be able to call votes but all standard votes to be timed out.
|
||||
|
||||
@@ -11,6 +11,9 @@ ui-vote-create-button = Call Vote
|
||||
# Timeout text if a standard vote type is currently on timeout.
|
||||
ui-vote-type-timeout = This vote was called too recently ({$remaining})
|
||||
|
||||
# Unavailable text if a vote type has been disabled manually.
|
||||
ui-vote-type-not-available = This vote type has been disabled
|
||||
|
||||
# Hue hue hue
|
||||
ui-vote-fluff = Powered by Robust™ Anti-Tamper Technology
|
||||
|
||||
|
||||
Reference in New Issue
Block a user