Files
wwdpublic/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs
Mnemotechnican d5f73ad370 Fix Them Pesky Job Requirements (#511)
# Description
Fixes job requirements using wrong locales

Happened because one function had role-timer- as its default locale
prefix and the other that called the first had null as the default.

---

<details><summary><h1>Media</h1></summary><p>


![image](https://github.com/Simple-Station/Einstein-Engines/assets/69920617/0d02c40a-a58f-4b48-89f5-e0a6b4ff75b9)


![image](https://github.com/Simple-Station/Einstein-Engines/assets/69920617/f3b651dd-492e-47c0-aa9f-74998c78f792)

</p></details>

---

# Changelog

<!--
You can add an author after the `🆑` to change the name that appears
in the changelog (ex: `🆑 Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->

🆑
- fix: Job requirements are now displayed correctly.
2024-07-05 20:10:24 +01:00

139 lines
4.3 KiB
C#

using System.Diagnostics.CodeAnalysis;
using Content.Shared.CCVar;
using Content.Shared.Players;
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Roles;
using Robust.Client;
using Robust.Client.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client.Players.PlayTimeTracking;
public sealed partial class JobRequirementsManager
{
[Dependency] private readonly IBaseClient _client = default!;
[Dependency] private readonly IClientNetManager _net = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IPrototypeManager _prototypes = default!;
public readonly Dictionary<string, TimeSpan> PlayTimes = new();
private readonly List<string> _roleBans = new();
private ISawmill _sawmill = default!;
public event Action? Updated;
public void Initialize()
{
_sawmill = Logger.GetSawmill("job_requirements");
// Yeah the client manager handles role bans and playtime but the server ones are separate DEAL.
_net.RegisterNetMessage<MsgRoleBans>(RxRoleBans);
_net.RegisterNetMessage<MsgPlayTime>(RxPlayTime);
_net.RegisterNetMessage<MsgWhitelist>(RxWhitelist);
_client.RunLevelChanged += ClientOnRunLevelChanged;
}
private void ClientOnRunLevelChanged(object? sender, RunLevelChangedEventArgs e)
{
if (e.NewLevel == ClientRunLevel.Initialize)
{
// Reset on disconnect, just in case.
PlayTimes.Clear();
}
}
private void RxRoleBans(MsgRoleBans message)
{
_sawmill.Debug($"Received roleban info containing {message.Bans.Count} entries.");
if (_roleBans.Equals(message.Bans))
return;
_roleBans.Clear();
_roleBans.AddRange(message.Bans);
Updated?.Invoke();
}
private void RxPlayTime(MsgPlayTime message)
{
PlayTimes.Clear();
// NOTE: do not assign _roles = message.Trackers due to implicit data sharing in integration tests.
foreach (var (tracker, time) in message.Trackers)
{
PlayTimes[tracker] = time;
}
/*var sawmill = Logger.GetSawmill("play_time");
foreach (var (tracker, time) in _roles)
{
sawmill.Info($"{tracker}: {time}");
}*/
Updated?.Invoke();
}
public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out FormattedMessage? reason)
{
reason = null;
if (_roleBans.Contains($"Job:{job.ID}"))
{
reason = FormattedMessage.FromUnformatted(Loc.GetString("role-ban"));
return false;
}
var player = _playerManager.LocalSession;
if (player == null)
return true;
return CheckRoleTime(job.Requirements, out reason);
}
public bool CheckRoleTime(HashSet<JobRequirement>? requirements, [NotNullWhen(false)] out FormattedMessage? reason, string? localePrefix = "role-timer-")
{
reason = null;
if (requirements == null || !_cfg.GetCVar(CCVars.GameRoleTimers))
return true;
var reasons = new List<string>();
foreach (var requirement in requirements)
{
if (JobRequirements.TryRequirementMet(requirement, PlayTimes, out var jobReason, _entManager, _prototypes, _whitelisted, localePrefix))
continue;
reasons.Add(jobReason.ToMarkup());
}
reason = reasons.Count == 0 ? null : FormattedMessage.FromMarkup(string.Join('\n', reasons));
return reason == null;
}
public TimeSpan FetchOverallPlaytime()
{
return PlayTimes.TryGetValue("Overall", out var overallPlaytime) ? overallPlaytime : TimeSpan.Zero;
}
public IEnumerable<KeyValuePair<string, TimeSpan>> FetchPlaytimeByRoles()
{
var jobsToMap = _prototypes.EnumeratePrototypes<JobPrototype>();
foreach (var job in jobsToMap)
{
if (PlayTimes.TryGetValue(job.PlayTimeTracker, out var locJobName))
{
yield return new KeyValuePair<string, TimeSpan>(job.Name, locJobName);
}
}
}
}