Play time tracking: Job timers 3: more titles: when the (#9978)

Co-authored-by: Veritius <veritiusgaming@gmail.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
Pieter-Jan Briers
2022-08-07 08:00:42 +02:00
committed by GitHub
parent 6b94db0336
commit e852ada6c8
91 changed files with 5044 additions and 247 deletions

View File

@@ -0,0 +1,96 @@
using System.Linq;
using Content.Server.Afk.Events;
using Content.Server.GameTicking;
using Content.Shared.CCVar;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Player;
namespace Content.Server.Afk;
/// <summary>
/// Actively checks for AFK players regularly and issues an event whenever they go afk.
/// </summary>
public sealed class AFKSystem : EntitySystem
{
[Dependency] private readonly IAfkManager _afkManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly GameTicker _ticker = default!;
private float _checkDelay;
private float _accumulator;
private readonly HashSet<IPlayerSession> _afkPlayers = new();
public override void Initialize()
{
base.Initialize();
_playerManager.PlayerStatusChanged += OnPlayerChange;
_configManager.OnValueChanged(CCVars.AfkTime, SetAfkDelay, true);
}
private void SetAfkDelay(float obj)
{
_checkDelay = obj;
}
private void OnPlayerChange(object? sender, SessionStatusEventArgs e)
{
switch (e.NewStatus)
{
case SessionStatus.Disconnected:
_afkPlayers.Remove(e.Session);
break;
}
}
public override void Shutdown()
{
base.Shutdown();
_afkPlayers.Clear();
_accumulator = 0f;
_playerManager.PlayerStatusChanged -= OnPlayerChange;
_configManager.UnsubValueChanged(CCVars.AfkTime, SetAfkDelay);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
if (_ticker.RunLevel != GameRunLevel.InRound)
{
_afkPlayers.Clear();
_accumulator = 0f;
return;
}
_accumulator += frameTime;
// TODO: Should also listen to the input events for more accurate timings.
if (_accumulator < _checkDelay) return;
_accumulator -= _checkDelay;
foreach (var session in Filter.GetAllPlayers())
{
var pSession = (IPlayerSession) session;
var isAfk = _afkManager.IsAfk(pSession);
if (isAfk && _afkPlayers.Add(pSession))
{
var ev = new AFKEvent(pSession);
RaiseLocalEvent(ref ev);
continue;
}
if (!isAfk && _afkPlayers.Remove(pSession))
{
var ev = new UnAFKEvent(pSession);
RaiseLocalEvent(ref ev);
continue;
}
}
}
}

View File

@@ -0,0 +1,17 @@
using Robust.Server.Player;
namespace Content.Server.Afk.Events;
/// <summary>
/// Raised whenever a player goes afk.
/// </summary>
[ByRefEvent]
public readonly struct AFKEvent
{
public readonly IPlayerSession Session;
public AFKEvent(IPlayerSession playerSession)
{
Session = playerSession;
}
}

View File

@@ -0,0 +1,17 @@
using Robust.Server.Player;
namespace Content.Server.Afk.Events;
/// <summary>
/// Raised whenever a player is no longer AFK.
/// </summary>
[ByRefEvent]
public readonly struct UnAFKEvent
{
public readonly IPlayerSession Session;
public UnAFKEvent(IPlayerSession playerSession)
{
Session = playerSession;
}
}

View File

@@ -8,13 +8,14 @@ namespace Content.Server.Afk
[AdminCommand(AdminFlags.Admin)]
public sealed class IsAfkCommand : IConsoleCommand
{
[Dependency] private readonly IPlayerManager _players = default!;
public string Command => "isafk";
public string Description => "Checks if a specified player is AFK";
public string Help => "Usage: isafk <playerName>";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var playerManager = IoCManager.Resolve<IPlayerManager>();
var afkManager = IoCManager.Resolve<IAfkManager>();
if (args.Length == 0)
@@ -23,7 +24,7 @@ namespace Content.Server.Afk
return;
}
if (!playerManager.TryGetSessionByUsername(args[0], out var player))
if (!_players.TryGetSessionByUsername(args[0], out var player))
{
shell.WriteError("Unable to find that player");
return;
@@ -31,5 +32,17 @@ namespace Content.Server.Afk
shell.WriteLine(afkManager.IsAfk(player) ? "They are indeed AFK" : "They are not AFK");
}
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
if (args.Length == 1)
{
return CompletionResult.FromHintOptions(
CompletionHelper.SessionNames(players: _players),
"<playerName>");
}
return CompletionResult.Empty;
}
}
}