* Add admin logging, models, migrations * Add logging damage changes * Add Log admin flag, LogFilter, Logs admin menu tab, message Refactor admin logging API * Change admin log get method names * Fix the name again * Minute amount of reorganization * Reset Postgres db snapshot * Reset Sqlite db snapshot * Make AdminLog have a composite primary key of round, id * Minute cleanup * Change admin system to do a type check instead of index check * Make admin logs use C# 10 interpolated string handlers * Implement UI on its own window Custom controls Searching Add admin log converters * Implement limits into the query * Change logs to be put into an OutputPanel instead for text wrapping * Add log <-> player m2m relationship back * UI improvements, make text wrap, add separators * Remove entity prefix from damaged log * Add explicit m2m model, fix any players filter * Add debug command to test bulk adding logs * Admin logs now just kinda go * Add histogram for database update time * Make admin log system update run every 5 seconds * Add a cap to the log queue and a metric for how many times it has been reached * Add metric for logs sent in a round * Make cvars out of admin logs queue send delay and cap * Merge fixes * Reset some changes * Add test for adding and getting a single log * Add tests for bulk adding logs * Add test for querying logs * Add CallerArgumentExpression to LogStringHandler methods and test * Improve UI, fix SQLite, add searching by round * Add entities to admin logs * Move distinct after orderby * Add migrations * ef core eat my ass * Add cvar for client logs batch size * Sort logs from newest to oldest by default * Merge fixes * Reorganize tests and add one for date ordering * Add note to log types to not change their numeric values * Add impacts to logs, better UI filtering * Make log add callable from shared for convenience * Get current round id directly from game ticker * Revert namespace change for DamageableSystem
135 lines
4.4 KiB
C#
135 lines
4.4 KiB
C#
using System.Linq;
|
|
using Content.Server.Administration.Managers;
|
|
using Content.Server.Players;
|
|
using Content.Server.Roles;
|
|
using Content.Server.Traitor;
|
|
using Content.Shared.Administration;
|
|
using Content.Shared.Administration.Events;
|
|
using Robust.Server.GameObjects;
|
|
using Robust.Server.Player;
|
|
using Robust.Shared.Enums;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.IoC;
|
|
|
|
namespace Content.Server.Administration
|
|
{
|
|
public class AdminSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
|
[Dependency] private readonly IAdminManager _adminManager = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
|
|
_adminManager.OnPermsChanged += OnAdminPermsChanged;
|
|
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttached);
|
|
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetached);
|
|
SubscribeLocalEvent<RoleAddedEvent>(OnRoleEvent);
|
|
SubscribeLocalEvent<RoleRemovedEvent>(OnRoleEvent);
|
|
}
|
|
|
|
private void OnRoleEvent(RoleEvent ev)
|
|
{
|
|
if (ev.Role.Antagonist && ev.Role.Mind.Session != null)
|
|
{
|
|
foreach (var admin in _adminManager.ActiveAdmins)
|
|
{
|
|
RaiseNetworkEvent(GetChangedEvent(ev.Role.Mind.Session), admin.ConnectedClient);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnAdminPermsChanged(AdminPermsChangedEventArgs obj)
|
|
{
|
|
if(!obj.IsAdmin)
|
|
{
|
|
RaiseNetworkEvent(new FullPlayerListEvent(), obj.Player.ConnectedClient);
|
|
return;
|
|
}
|
|
|
|
SendFullPlayerList(obj.Player);
|
|
}
|
|
|
|
private void OnPlayerDetached(PlayerDetachedEvent ev)
|
|
{
|
|
if(ev.Player.Status == SessionStatus.Disconnected) return;
|
|
|
|
foreach (var admin in _adminManager.ActiveAdmins)
|
|
{
|
|
RaiseNetworkEvent(GetChangedEvent(ev.Player), admin.ConnectedClient);
|
|
}
|
|
}
|
|
|
|
private void OnPlayerAttached(PlayerAttachedEvent ev)
|
|
{
|
|
if(ev.Player.Status == SessionStatus.Disconnected) return;
|
|
|
|
foreach (var admin in _adminManager.ActiveAdmins)
|
|
{
|
|
RaiseNetworkEvent(GetChangedEvent(ev.Player), admin.ConnectedClient);
|
|
}
|
|
}
|
|
|
|
public override void Shutdown()
|
|
{
|
|
base.Shutdown();
|
|
_playerManager.PlayerStatusChanged -= OnPlayerStatusChanged;
|
|
_adminManager.OnPermsChanged -= OnAdminPermsChanged;
|
|
}
|
|
|
|
private PlayerInfoChangedEvent GetChangedEvent(IPlayerSession session)
|
|
{
|
|
return new()
|
|
{
|
|
PlayerInfo = GetPlayerInfo(session),
|
|
};
|
|
}
|
|
|
|
private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
|
|
{
|
|
EntityEventArgs? args = null;
|
|
switch (e.NewStatus)
|
|
{
|
|
case SessionStatus.InGame:
|
|
case SessionStatus.Connected:
|
|
args = GetChangedEvent(e.Session);
|
|
break;
|
|
case SessionStatus.Disconnected:
|
|
args = new PlayerInfoRemovalMessage {NetUserId = e.Session.UserId};
|
|
break;
|
|
}
|
|
|
|
if(args == null) return;
|
|
|
|
foreach (var admin in _adminManager.AllAdmins)
|
|
{
|
|
RaiseNetworkEvent(args, admin.ConnectedClient);
|
|
}
|
|
}
|
|
|
|
private void SendFullPlayerList(IPlayerSession playerSession)
|
|
{
|
|
var ev = new FullPlayerListEvent();
|
|
ev.PlayersInfo.Clear();
|
|
foreach (var session in _playerManager.GetAllPlayers())
|
|
{
|
|
ev.PlayersInfo.Add(GetPlayerInfo(session));
|
|
}
|
|
|
|
RaiseNetworkEvent(ev, playerSession.ConnectedClient);
|
|
}
|
|
|
|
private PlayerInfo GetPlayerInfo(IPlayerSession session)
|
|
{
|
|
var name = session.Name;
|
|
var username = session.AttachedEntity?.Name ?? string.Empty;
|
|
var antag = session.ContentData()?.Mind?.AllRoles.Any(r => r.Antagonist) ?? false;
|
|
var uid = session.AttachedEntity?.Uid ?? EntityUid.Invalid;
|
|
|
|
return new PlayerInfo(name, username, antag, uid, session.UserId);
|
|
}
|
|
}
|
|
}
|