using Content.Server.Database;
using Content.Server.Players.PlayTimeTracking;
using Content.Server.Players.Whitelist;
using Content.Shared.CCVar;
using Content.Shared.NewPlayer;
using Content.Shared.GameTicking;
using Content.Shared.Ghost.Components;
using Robust.Shared.Configuration;
using Robust.Shared.GameStates;
using Robust.Shared.Player;
namespace Content.Server.NewPlayer;
///
/// Used to set "new player" icons, and to manage the components to only have them visible to players with .
///
public sealed partial class NewPlayerSystem : EntitySystem
{
[Dependency] private IConfigurationManager _config = default!;
[Dependency] private PlayTimeTrackingManager _playtimeManager = default!;
[Dependency] private WhitelistManager _whitelistManager = default!;
[Dependency] private EntityQuery _showPlayerIconQuery = default!;
private TimeSpan _newPlayerTimeTotal;
///
public override void Initialize()
{
base.Initialize();
Subs.CVar(_config, CCVars.NewPlayerTimeTotalMinutes, v => _newPlayerTimeTotal = TimeSpan.FromMinutes(v), true);
}
[SubscribeLocalEvent]
private void OnNewPlayerGetStateAttempt(Entity entity, ref ComponentGetStateAttemptEvent args)
{
args.Cancelled = !(args.Player?.AttachedEntity is not { } uid || _showPlayerIconQuery.HasComp(uid));
}
///
/// This is a bit of a "hack" to ensure that the component states are properly updated in the event a component
/// is removed out of when the client isn't here to receive it. It's taken from how SharedRevolutionarySystem does it.
/// TODO: It's not ideal, and preferably we'd have a more solid way to handle specific session component handling.
///
[SubscribeLocalEvent]
private void OnComponentStartup(Entity entity, ref ComponentStartup args)
{
var newPlayerQuery = AllEntityQuery();
while (newPlayerQuery.MoveNext(out var uid, out var comp))
{
Dirty(uid, comp);
}
}
[SubscribeLocalEvent]
private void OnPlayerSpawnComplete(PlayerSpawnCompleteEvent ev)
{
// Give to players who should see
if (_whitelistManager.IsConnectedWhitelisted(ev.Player)) // TODO: This should use permissions from a Mentor group or similar, as this only checks manual whitelisting.
EnsureComp(ev.Mob);
// Give the players who should have it
try
{
var totalTime = _playtimeManager.GetOverallPlaytime(ev.Player);
if (totalTime < _newPlayerTimeTotal)
EnsureComp(ev.Mob);
}
catch (Exception e)
{
Log.Error($"Error getting new player playtime:\n{e}");
}
}
[SubscribeLocalEvent]
private void OnPlayerAttachedEvent(Entity ent, ref PlayerAttachedEvent ev)
{
if (_whitelistManager.IsConnectedWhitelisted(ev.Player))
EnsureComp(ev.Entity);
}
}