Role whitelists (#191)

* Add job whitelists

* Redo whitelist system with jobrequirements

* Remove unused function

* Fix linter errors

* Remove unused dependency and whitespace
This commit is contained in:
Debug 2023-10-19 00:23:17 +02:00 committed by GitHub
parent f06fc04768
commit c37a4d53c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 143 additions and 10 deletions

View File

@ -0,0 +1,22 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared.CCVar;
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Roles;
using Robust.Shared.Utility;
namespace Content.Client.Players.PlayTimeTracking;
public sealed partial class JobRequirementsManager
{
private bool _whitelisted = false;
private void RxWhitelist(MsgWhitelist message)
{
_whitelisted = message.Whitelisted;
}
public bool IsWhitelisted()
{
return _whitelisted;
}
}

View File

@ -14,7 +14,7 @@ using Robust.Shared.Utility;
namespace Content.Client.Players.PlayTimeTracking;
public sealed class JobRequirementsManager
public sealed partial class JobRequirementsManager
{
[Dependency] private readonly IBaseClient _client = default!;
[Dependency] private readonly IClientNetManager _net = default!;
@ -37,6 +37,7 @@ public sealed class JobRequirementsManager
// 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;
}
@ -113,7 +114,7 @@ public sealed class JobRequirementsManager
var reasons = new List<string>();
foreach (var requirement in requirements)
{
if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes))
if (JobRequirements.TryRequirementMet(requirement, _roles, out var jobReason, _entManager, _prototypes, _whitelisted))
continue;
reasons.Add(jobReason.ToMarkup());

View File

@ -128,6 +128,8 @@ namespace Content.Server.GameTicking
{
await _userDb.WaitLoadComplete(session);
session.ContentData()!.Whitelisted = await _db.GetWhitelistStatusAsync(session.UserId); // Nyanotrasen - Whitelist
SpawnPlayer(session, EntityUid.Invalid);
}

View File

@ -0,0 +1,20 @@
using Content.Server.Players;
using Content.Shared.Players.PlayTimeTracking;
using Robust.Server.Player;
namespace Content.Server.Players.PlayTimeTracking;
public sealed partial class PlayTimeTrackingManager
{
public void SendWhitelistCached(IPlayerSession playerSession)
{
var whitelist = playerSession.ContentData()?.Whitelisted ?? false;
var msg = new MsgWhitelist
{
Whitelisted = whitelist
};
_net.ServerSendMessage(msg, playerSession.ConnectedClient);
}
}

View File

@ -54,7 +54,7 @@ public delegate void CalcPlayTimeTrackersCallback(IPlayerSession player, HashSet
/// Operations like refreshing and sending play time info to clients are deferred until the next frame (note: not tick).
/// </para>
/// </remarks>
public sealed class PlayTimeTrackingManager
public sealed partial class PlayTimeTrackingManager
{
[Dependency] private readonly IServerDbManager _db = default!;
[Dependency] private readonly IServerNetManager _net = default!;
@ -85,6 +85,7 @@ public sealed class PlayTimeTrackingManager
_sawmill = Logger.GetSawmill("play_time");
_net.RegisterNetMessage<MsgPlayTime>();
_net.RegisterNetMessage<MsgWhitelist>(); // Nyanotrasen - Whitelist status
_cfg.OnValueChanged(CCVars.PlayTimeSaveInterval, f => _saveInterval = TimeSpan.FromSeconds(f), true);
}

View File

@ -165,7 +165,9 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
var playTimes = _tracking.GetTrackerTimes(player);
return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes);
var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
return JobRequirements.TryRequirementsMet(job, playTimes, out _, EntityManager, _prototypes, isWhitelisted);
}
public HashSet<string> GetDisallowedJobs(IPlayerSession player)
@ -175,6 +177,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
return roles;
var playTimes = _tracking.GetTrackerTimes(player);
var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
foreach (var job in _prototypes.EnumeratePrototypes<JobPrototype>())
{
@ -182,7 +185,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
{
foreach (var requirement in job.Requirements)
{
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes, isWhitelisted))
continue;
goto NoRole;
@ -209,6 +212,8 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
playTimes ??= new Dictionary<string, TimeSpan>();
}
var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement
for (var i = 0; i < jobs.Count; i++)
{
var job = jobs[i];
@ -220,7 +225,7 @@ public sealed class PlayTimeTrackingSystem : EntitySystem
foreach (var requirement in jobber.Requirements)
{
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes))
if (JobRequirements.TryRequirementMet(requirement, playTimes, out _, EntityManager, _prototypes, isWhitelisted))
continue;
jobs.RemoveSwap(i);

View File

@ -1,7 +1,9 @@
using Content.Server.Administration;
using Content.Server.Database;
using Content.Server.Players.PlayTimeTracking;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Players;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
@ -22,6 +24,8 @@ public sealed class AddWhitelistCommand : IConsoleCommand
var db = IoCManager.Resolve<IServerDbManager>();
var loc = IoCManager.Resolve<IPlayerLocator>();
var player = IoCManager.Resolve<IPlayerManager>();
var playtime = IoCManager.Resolve<PlayTimeTrackingManager>();
var name = args[0];
var data = await loc.LookupIdByNameAsync(name);
@ -37,6 +41,15 @@ public sealed class AddWhitelistCommand : IConsoleCommand
}
await db.AddToWhitelistAsync(guid);
// Nyanotrasen - Update whitelist status in player data.
if (player.TryGetPlayerDataByUsername(name, out var playerData) &&
player.TryGetSessionByUsername(name, out var session))
{
playerData.ContentData()!.Whitelisted = true;
playtime.SendWhitelistCached(session);
}
shell.WriteLine(Loc.GetString("command-whitelistadd-added", ("username", data.Username)));
return;
}
@ -58,6 +71,8 @@ public sealed class RemoveWhitelistCommand : IConsoleCommand
var db = IoCManager.Resolve<IServerDbManager>();
var loc = IoCManager.Resolve<IPlayerLocator>();
var player = IoCManager.Resolve<IPlayerManager>();
var playtime = IoCManager.Resolve<PlayTimeTrackingManager>();
var name = args[0];
var data = await loc.LookupIdByNameAsync(name);
@ -73,6 +88,15 @@ public sealed class RemoveWhitelistCommand : IConsoleCommand
}
await db.RemoveFromWhitelistAsync(guid);
// Nyanotrasen - Update whitelist status in player data.
if (player.TryGetPlayerDataByUsername(name, out var playerData) &&
player.TryGetSessionByUsername(name, out var session))
{
playerData.ContentData()!.Whitelisted = false;
playtime.SendWhitelistCached(session);
}
shell.WriteLine(Loc.GetString("command-whitelistremove-removed", ("username", data.Username)));
return;
}

View File

@ -0,0 +1,11 @@
using JetBrains.Annotations;
using Robust.Shared.Serialization;
namespace Content.Shared.Roles
{
[UsedImplicitly]
[Serializable, NetSerializable]
public sealed partial class WhitelistRequirement : JobRequirement
{
}
}

View File

@ -0,0 +1,25 @@
using Lidgren.Network;
using Robust.Shared.Network;
using Robust.Shared.Serialization;
namespace Content.Shared.Players.PlayTimeTracking;
/// <summary>
/// Sent server -> client to inform the client of their whitelist status.
/// </summary>
public sealed class MsgWhitelist : NetMessage
{
public override MsgGroups MsgGroup => MsgGroups.EntityEvent;
public bool Whitelisted = false;
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
{
Whitelisted = buffer.ReadBoolean();
}
public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
{
buffer.Write(Whitelisted);
}
}

View File

@ -38,6 +38,12 @@ public sealed class PlayerData
/// </summary>
public bool ExplicitlyDeadminned { get; set; }
/// <summary>
/// Nyanotrasen - Are they whitelisted? Lets us avoid async.
/// </summary>
[ViewVariables]
public bool Whitelisted { get; set; }
public PlayerData(NetUserId userId, string name)
{
UserId = userId;

View File

@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis;
using Content.Shared.Players.PlayTimeTracking;
using Content.Shared.Roles.Jobs;
using JetBrains.Annotations;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@ -76,7 +77,8 @@ namespace Content.Shared.Roles
Dictionary<string, TimeSpan> playTimes,
[NotNullWhen(false)] out FormattedMessage? reason,
IEntityManager entManager,
IPrototypeManager prototypes)
IPrototypeManager prototypes,
bool isWhitelisted)
{
reason = null;
if (job.Requirements == null)
@ -84,7 +86,7 @@ namespace Content.Shared.Roles
foreach (var requirement in job.Requirements)
{
if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes))
if (!TryRequirementMet(requirement, playTimes, out reason, entManager, prototypes, isWhitelisted))
return false;
}
@ -99,7 +101,8 @@ namespace Content.Shared.Roles
Dictionary<string, TimeSpan> playTimes,
[NotNullWhen(false)] out FormattedMessage? reason,
IEntityManager entManager,
IPrototypeManager prototypes)
IPrototypeManager prototypes,
bool isWhitelisted)
{
reason = null;
@ -216,6 +219,15 @@ namespace Content.Shared.Roles
return true;
}
case WhitelistRequirement _: // DeltaV - Whitelist requirement
if (isWhitelisted == null)
throw new ArgumentNullException(nameof(isWhitelisted), "isWhitelisted cannot be null.");
if (isWhitelisted)
return true;
reason = FormattedMessage.FromMarkup(Loc.GetString("playtime-deny-reason-not-whitelisted"));
return false;
default:
throw new NotImplementedException();
}

View File

@ -0,0 +1 @@
playtime-deny-reason-not-whitelisted = You need to be whitelisted.

View File

@ -33,4 +33,5 @@
- !type:DepartmentTimeRequirement
department: Security
time: 18000 # 5h
- !type:WhitelistRequirement # DeltaV - Commander is an "hrp" role
# should be changed to nukie playtime when thats tracked (wyci)

View File

@ -24,6 +24,7 @@
time: 108000 # DeltaV - 30 hours
- !type:OverallPlaytimeRequirement # DeltaV - Playtime requirement
time: 108000 # 30 hours
- !type:WhitelistRequirement # DeltaV - Whitelist requirement
weight: 20
startingGear: CaptainGear
icon: "JobIconCaptain"

View File

@ -15,6 +15,7 @@
time: 36000 # 10 hours
- !type:OverallPlaytimeRequirement
time: 90000 # DeltaV - 25 hours
- !type:WhitelistRequirement # DeltaV - Whitelist requirement
weight: 10
startingGear: HoSGear
icon: "JobIconHeadOfSecurity"
@ -41,7 +42,7 @@
components:
- type: PsionicBonusChance #Nyano - Summary: makes it more likely to become psionic.
flatBonus: 0.025
- type: startingGear
id: HoSGear
equipment: