Skip to content

Commit fbba872

Browse files
authored
Job Whitelisting support (#440)
* Role whitelists (#191) * Add job whitelists * Redo whitelist system with jobrequirements * Remove unused function * Fix linter errors * Remove unused dependency and whitespace * Make the proper job whitelisted
1 parent 68712a1 commit fbba872

File tree

14 files changed

+115
-15
lines changed

14 files changed

+115
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
using Content.Shared.CCVar;
3+
using Content.Shared.Players.PlayTimeTracking;
4+
using Content.Shared.Roles;
5+
using Robust.Shared.Utility;
6+
7+
namespace Content.Client.Players.PlayTimeTracking;
8+
9+
public sealed partial class JobRequirementsManager
10+
{
11+
private bool _whitelisted = false;
12+
13+
private void RxWhitelist(MsgWhitelist message)
14+
{
15+
_whitelisted = message.Whitelisted;
16+
}
17+
18+
public bool IsWhitelisted()
19+
{
20+
return _whitelisted;
21+
}
22+
}

Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs

+3-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace Content.Client.Players.PlayTimeTracking;
1616

17-
public sealed class JobRequirementsManager
17+
public sealed partial class JobRequirementsManager
1818
{
1919
[Dependency] private readonly IBaseClient _client = default!;
2020
[Dependency] private readonly IClientNetManager _net = default!;
@@ -30,8 +30,6 @@ public sealed class JobRequirementsManager
3030

3131
public event Action? Updated;
3232

33-
private bool _whitelisted = false;
34-
3533
public void Initialize()
3634
{
3735
_sawmill = Logger.GetSawmill("job_requirements");
@@ -40,6 +38,7 @@ public void Initialize()
4038
_net.RegisterNetMessage<MsgRoleBans>(RxRoleBans);
4139
_net.RegisterNetMessage<MsgPlayTime>(RxPlayTime);
4240
_net.RegisterNetMessage<MsgWhitelist>(RxWhitelist);
41+
4342
_client.RunLevelChanged += ClientOnRunLevelChanged;
4443
}
4544

@@ -81,10 +80,6 @@ private void RxPlayTime(MsgPlayTime message)
8180
}*/
8281
Updated?.Invoke();
8382
}
84-
private void RxWhitelist(MsgWhitelist message)
85-
{
86-
_whitelisted = message.Whitelisted;
87-
}
8883

8984
public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out FormattedMessage? reason)
9085
{
@@ -119,7 +114,7 @@ public bool CheckRoleTime(HashSet<JobRequirement>? requirements, [NotNullWhen(fa
119114
var reasons = new List<string>();
120115
foreach (var requirement in requirements)
121116
{
122-
if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes))
117+
if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes, _whitelisted))
123118
continue;
124119

125120
reasons.Add(jobReason.ToMarkup());

Content.Server/GameTicking/GameTicker.Player.cs

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ async void SpawnWaitDb()
128128
{
129129
await _userDb.WaitLoadComplete(session);
130130

131+
session.ContentData()!.Whitelisted = await _db.GetWhitelistStatusAsync(session.UserId); // Nyanotrasen - Whitelist
132+
131133
SpawnPlayer(session, EntityUid.Invalid);
132134
}
133135

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Content.Server.Players;
2+
using Content.Shared.Players.PlayTimeTracking;
3+
using Robust.Server.Player;
4+
5+
namespace Content.Server.Players.PlayTimeTracking;
6+
7+
public sealed partial class PlayTimeTrackingManager
8+
{
9+
public void SendWhitelistCached(IPlayerSession playerSession)
10+
{
11+
var whitelist = playerSession.ContentData()?.Whitelisted ?? false;
12+
13+
var msg = new MsgWhitelist
14+
{
15+
Whitelisted = whitelist
16+
};
17+
18+
_net.ServerSendMessage(msg, playerSession.ConnectedClient);
19+
}
20+
}

Content.Server/Players/PlayTimeTracking/PlayTimeTrackingManager.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ namespace Content.Server.Players.PlayTimeTracking;
5454
/// Operations like refreshing and sending play time info to clients are deferred until the next frame (note: not tick).
5555
/// </para>
5656
/// </remarks>
57-
public sealed class PlayTimeTrackingManager
57+
public sealed partial class PlayTimeTrackingManager
5858
{
5959
[Dependency] private readonly IServerDbManager _db = default!;
6060
[Dependency] private readonly IServerNetManager _net = default!;

Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ public bool IsAllowed(IPlayerSession player, string role)
165165

166166
var playTimes = _tracking.GetTrackerTimes(player);
167167

168-
return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes);
168+
var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
169+
170+
return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, isWhitelisted);
169171
}
170172

171173
public HashSet<string> GetDisallowedJobs(IPlayerSession player)
@@ -175,14 +177,15 @@ public HashSet<string> GetDisallowedJobs(IPlayerSession player)
175177
return roles;
176178

177179
var playTimes = _tracking.GetTrackerTimes(player);
180+
var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
178181

179182
foreach (var job in _prototypes.EnumeratePrototypes<JobPrototype>())
180183
{
181184
if (job.Requirements != null)
182185
{
183186
foreach (var requirement in job.Requirements)
184187
{
185-
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
188+
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes, isWhitelisted))
186189
continue;
187190

188191
goto NoRole;
@@ -209,6 +212,8 @@ public void RemoveDisallowedJobs(NetUserId userId, ref List<string> jobs)
209212
playTimes ??= new Dictionary<string, TimeSpan>();
210213
}
211214

215+
var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
216+
212217
for (var i = 0; i < jobs.Count; i++)
213218
{
214219
var job = jobs[i];
@@ -220,7 +225,7 @@ public void RemoveDisallowedJobs(NetUserId userId, ref List<string> jobs)
220225

221226
foreach (var requirement in jobber.Requirements)
222227
{
223-
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
228+
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes, isWhitelisted))
224229
continue;
225230

226231
jobs.RemoveSwap(i);

Content.Server/Whitelist/WhitelistCommands.cs

+24
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using Content.Server.Administration;
22
using Content.Server.Database;
3+
using Content.Server.Players.PlayTimeTracking;
34
using Content.Shared.Administration;
45
using Content.Shared.CCVar;
6+
using Content.Shared.Players;
57
using Robust.Server.Player;
68
using Robust.Shared.Configuration;
79
using Robust.Shared.Console;
@@ -22,6 +24,8 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
2224

2325
var db = IoCManager.Resolve<IServerDbManager>();
2426
var loc = IoCManager.Resolve<IPlayerLocator>();
27+
var player = IoCManager.Resolve<IPlayerManager>();
28+
var playtime = IoCManager.Resolve<PlayTimeTrackingManager>();
2529

2630
var name = args[0];
2731
var data = await loc.LookupIdByNameAsync(name);
@@ -37,6 +41,15 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
3741
}
3842

3943
await db.AddToWhitelistAsync(guid);
44+
45+
// Nyanotrasen - Update whitelist status in player data.
46+
if (player.TryGetPlayerDataByUsername(name, out var playerData) &&
47+
player.TryGetSessionByUsername(name, out var session))
48+
{
49+
playerData.ContentData()!.Whitelisted = true;
50+
playtime.SendWhitelistCached(session);
51+
}
52+
4053
shell.WriteLine(Loc.GetString("command-whitelistadd-added", ("username", data.Username)));
4154
return;
4255
}
@@ -58,6 +71,8 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
5871

5972
var db = IoCManager.Resolve<IServerDbManager>();
6073
var loc = IoCManager.Resolve<IPlayerLocator>();
74+
var player = IoCManager.Resolve<IPlayerManager>();
75+
var playtime = IoCManager.Resolve<PlayTimeTrackingManager>();
6176

6277
var name = args[0];
6378
var data = await loc.LookupIdByNameAsync(name);
@@ -73,6 +88,15 @@ public async void Execute(IConsoleShell shell, string argStr, string[] args)
7388
}
7489

7590
await db.RemoveFromWhitelistAsync(guid);
91+
92+
// Nyanotrasen - Update whitelist status in player data.
93+
if (player.TryGetPlayerDataByUsername(name, out var playerData) &&
94+
player.TryGetSessionByUsername(name, out var session))
95+
{
96+
playerData.ContentData()!.Whitelisted = false;
97+
playtime.SendWhitelistCached(session);
98+
}
99+
76100
shell.WriteLine(Loc.GetString("command-whitelistremove-removed", ("username", data.Username)));
77101
return;
78102
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using JetBrains.Annotations;
2+
using Robust.Shared.Serialization;
3+
4+
namespace Content.Shared.Roles
5+
{
6+
[UsedImplicitly]
7+
[Serializable, NetSerializable]
8+
public sealed partial class WhitelistRequirement : JobRequirement
9+
{
10+
}
11+
}

Content.Shared/Players/PlayerData.cs

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ public sealed class PlayerData
3838
/// </summary>
3939
public bool ExplicitlyDeadminned { get; set; }
4040

41+
/// <summary>
42+
/// Nyanotrasen - Are they whitelisted? Lets us avoid async.
43+
/// </summary>
44+
[ViewVariables]
45+
public bool Whitelisted { get; set; }
46+
4147
public PlayerData(NetUserId userId, string name)
4248
{
4349
UserId = userId;

Content.Shared/Roles/JobRequirements.cs

+15-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Content.Shared.Players.PlayTimeTracking;
33
using Content.Shared.Roles.Jobs;
44
using JetBrains.Annotations;
5+
using Robust.Shared.Players;
56
using Robust.Shared.Prototypes;
67
using Robust.Shared.Serialization;
78
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -76,15 +77,16 @@ public static bool TryRequirementsMet(
7677
Dictionary<string, TimeSpan> playTimes,
7778
[NotNullWhen(false)] out FormattedMessage? reason,
7879
IEntityManager entManager,
79-
IPrototypeManager prototypes)
80+
IPrototypeManager prototypes,
81+
bool isWhitelisted)
8082
{
8183
reason = null;
8284
if (job.Requirements == null)
8385
return true;
8486

8587
foreach (var requirement in job.Requirements)
8688
{
87-
if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes))
89+
if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes, isWhitelisted))
8890
return false;
8991
}
9092

@@ -99,7 +101,8 @@ public static bool TryRequirementMet(
99101
Dictionary<string, TimeSpan> playTimes,
100102
[NotNullWhen(false)] out FormattedMessage? reason,
101103
IEntityManager entManager,
102-
IPrototypeManager prototypes)
104+
IPrototypeManager prototypes,
105+
bool isWhitelisted)
103106
{
104107
reason = null;
105108

@@ -216,6 +219,15 @@ public static bool TryRequirementMet(
216219

217220
return true;
218221
}
222+
case WhitelistRequirement _: // DeltaV - Whitelist requirement
223+
if (isWhitelisted == null)
224+
throw new ArgumentNullException(nameof(isWhitelisted), "isWhitelisted cannot be null.");
225+
226+
if (isWhitelisted)
227+
return true;
228+
229+
reason = FormattedMessage.FromMarkup(Loc.GetString("playtime-deny-reason-not-whitelisted"));
230+
return false;
219231
default:
220232
throw new NotImplementedException();
221233
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
playtime-deny-reason-not-whitelisted = You need to be whitelisted.

Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
requirements:
77
- !type:OverallPlaytimeRequirement
88
time: 36000
9+
- !type:WhitelistRequirement
910
weight: 20
1011
startingGear: HoPGear
1112
icon: "JobIconHeadOfPersonnel"

Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
requirements:
77
- !type:OverallPlaytimeRequirement
88
time: 50400
9+
- !type:WhitelistRequirement
910
# - !type:RoleTimeRequirement
1011
# role: JobWarden
1112
# time: 21600 #6 hrs

0 commit comments

Comments
 (0)