diff --git a/Content.Server/White/Reputation/ReputationManager.cs b/Content.Server/White/Reputation/ReputationManager.cs index 7bb947d612..0d709c0842 100644 --- a/Content.Server/White/Reputation/ReputationManager.cs +++ b/Content.Server/White/Reputation/ReputationManager.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Threading.Tasks; using Content.Server.Database; +using Content.Server.GameTicking; using Content.Shared.GameTicking; using Content.Shared.White.Reputation; using Robust.Server.Player; @@ -17,6 +18,7 @@ public sealed class ReputationManager : EntitySystem [Dependency] private readonly IRobustRandom _random = default!; private readonly Dictionary _cacheReputation = new(); + private readonly Dictionary _playerConnectionTime = new(); public override void Initialize() { @@ -29,11 +31,17 @@ public sealed class ReputationManager : EntitySystem SubscribeLocalEvent(OnRoundRestartCleanup); SubscribeLocalEvent(UpdateCachedReputation); + SubscribeLocalEvent(OnPlayerSpawn); } #region Cache - private void OnConnected(object? sender, NetChannelArgs e) + private void OnPlayerSpawn(PlayerBeforeSpawnEvent ev) + { + _playerConnectionTime.Add(ev.Player.UserId, DateTime.UtcNow); + } + + private void OnConnected(object? sender, NetChannelArgs e) { _cacheReputation.TryGetValue(e.Channel.UserId, out var info); var msg = new ReputationNetMsg() { Info = info }; @@ -75,6 +83,7 @@ public sealed class ReputationManager : EntitySystem .ToDictionary(player => player.Key, player => player.Value); _cacheReputation.Clear(); + _playerConnectionTime.Clear(); foreach (var kvp in newDictionary) { @@ -84,7 +93,6 @@ public sealed class ReputationManager : EntitySystem #endregion - #region PublicApi public async void SetPlayerReputation(NetUserId player, float value) @@ -114,6 +122,13 @@ public sealed class ReputationManager : EntitySystem return success; } + public bool GetCachedPlayerConnection(NetUserId player, out DateTime date) + { + var success = _playerConnectionTime.TryGetValue(player, out var dateTime); + date = dateTime; + return success; + } + public int GetPlayerWeight(float reputation) { return reputation switch diff --git a/Content.Server/White/Reputation/ReputationSystem.cs b/Content.Server/White/Reputation/ReputationSystem.cs index 3926336a3f..88b5a2b0fc 100644 --- a/Content.Server/White/Reputation/ReputationSystem.cs +++ b/Content.Server/White/Reputation/ReputationSystem.cs @@ -1,5 +1,4 @@ using System.Linq; -using System.Threading.Tasks; using Content.Server.Administration; using Content.Server.GameTicking; using Content.Server.Mind.Components; @@ -7,8 +6,9 @@ using Content.Server.UtkaIntegration; using Content.Server.White.AspectsSystem.Base; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; +using Content.Shared.White; using Robust.Server.Player; -using Robust.Shared.Asynchronous; +using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Utility; @@ -19,8 +19,12 @@ public sealed class ReputationSystem : EntitySystem [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly ReputationManager _repManager = default!; [Dependency] private readonly GameTicker _gameTicker = default!; - [Dependency] private readonly ITaskManager _taskManager = default!; [Dependency] private readonly IPlayerLocator _locator = default!; + [Dependency] private readonly IConfigurationManager _cfg = default!; + + private const int MinPlayers = 15; + private const int MinRoundLength = 25; + private const int MinTimePlayerConnected = 20; public override void Initialize() { @@ -41,6 +45,10 @@ public sealed class ReputationSystem : EntitySystem newValue = null; deltaValue = null; + var repEnabled = _cfg.GetCVar(WhiteCVars.ReputationEnabled); + if (!repEnabled) + return false; + if (!_playerManager.TryGetSessionByUsername(name, out var session) || session.AttachedEntity == null) return false; @@ -53,13 +61,17 @@ public sealed class ReputationSystem : EntitySystem if (value == null) return false; - var longRound = _gameTicker.RoundDuration().Minutes >= 25; - if (delta != 0 && longRound) + var longConnected = _repManager.GetCachedPlayerConnection(uid, out var date) + && DateTime.UtcNow - date >= TimeSpan.FromMinutes(MinTimePlayerConnected); + var longRound = _gameTicker.RoundDuration() >= TimeSpan.FromMinutes(MinRoundLength); + var enoughPlayers = _playerManager.PlayerCount >= MinPlayers; + + if (delta != 0 && longRound && longConnected && enoughPlayers) { _repManager.ModifyPlayerReputation(uid, delta); } - deltaValue = longRound ? delta : 0f; + deltaValue = longRound && longConnected && enoughPlayers ? delta : 0f; newValue = value + deltaValue; return true; diff --git a/Content.Shared/White/WhiteCVars.cs b/Content.Shared/White/WhiteCVars.cs index 7ccf568c31..58e78741a0 100644 --- a/Content.Shared/White/WhiteCVars.cs +++ b/Content.Shared/White/WhiteCVars.cs @@ -327,4 +327,9 @@ public sealed class WhiteCVars public static readonly CVarDef SalusApiLink = CVarDef.Create("white.salus_api_link", "http://localhost:7100/vpnchecker?address=", CVar.SERVERONLY | CVar.CONFIDENTIAL); + /* + * Reputation + */ + public static readonly CVarDef ReputationEnabled = + CVarDef.Create("white.reputation_enabled", true, CVar.SERVERONLY); }