Support player sessions in admin logs and add test

Fix EventRan log type id
Make slipping low impact
This commit is contained in:
DrSmugleaf
2021-11-22 23:15:22 +01:00
parent ce94c28e8a
commit 7b5878b846
6 changed files with 170 additions and 65 deletions

View File

@@ -1,11 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Database; using Content.Server.Database;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using NUnit.Framework; using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -194,4 +196,49 @@ public class AddTests : ContentIntegrationTest
return count >= amount; return count >= amount;
}); });
} }
[Test]
public async Task AddPlayerSessionLog()
{
var (client, server) = await StartConnectedServerClientPair(serverOptions: new ServerContentIntegrationOption
{
CVarOverrides =
{
[CCVars.AdminLogsQueueSendDelay.Name] = "0"
},
Pool = true
});
await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync());
var sPlayers = server.ResolveDependency<IPlayerManager>();
var sSystems = server.ResolveDependency<IEntitySystemManager>();
var sAdminLogSystem = sSystems.GetEntitySystem<AdminLogSystem>();
Guid playerGuid = default;
await server.WaitPost(() =>
{;
var player = sPlayers.ServerSessions.First();
playerGuid = player.UserId;
Assert.DoesNotThrow(() =>
{
sAdminLogSystem.Add(LogType.Unknown, $"{player:Player} test log.");
});
});
await WaitUntil(server, async () =>
{
var logs = sAdminLogSystem.CurrentRoundLogs();
await foreach (var log in logs)
{
Assert.That(log.Players, Does.Contain(playerGuid));
return true;
}
return false;
});
}
} }

View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Content.Server.Administration.Logs.Converters;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.Administration.Logs;
public partial class AdminLogSystem
{
private static readonly JsonNamingPolicy NamingPolicy = JsonNamingPolicy.CamelCase;
// Init only
private JsonSerializerOptions _jsonOptions = default!;
private void InitializeJson()
{
_jsonOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = NamingPolicy
};
foreach (var converter in _reflection.FindTypesWithAttribute<AdminLogConverterAttribute>())
{
var instance = _typeFactory.CreateInstance<JsonConverter>(converter);
_jsonOptions.Converters.Add(instance);
}
var converterNames = _jsonOptions.Converters.Select(converter => converter.GetType().Name);
_sawmill.Info($"Admin log converters found: {string.Join(" ", converterNames)}");
}
private (JsonDocument json, List<Guid> players, List<(int id, string? name)> entities) ToJson(
Dictionary<string, object?> properties)
{
var entities = new List<(int id, string? name)>();
var players = new List<Guid>();
var parsed = new Dictionary<string, object?>();
foreach (var key in properties.Keys)
{
var value = properties[key];
value = value switch
{
IPlayerSession player => new SerializablePlayer(player),
_ => value
};
var parsedKey = NamingPolicy.ConvertName(key);
parsed.Add(parsedKey, value);
EntityUid? entityId = properties[key] switch
{
EntityUid id => id,
IEntity entity => entity.Uid,
IPlayerSession {AttachedEntityUid: { }} session => session.AttachedEntityUid.Value,
IComponent component => component.OwnerUid,
_ => null
};
if (entityId is not { } uid)
{
continue;
}
var entityName = _entityManager.TryGetEntity(uid, out var resolvedEntity)
? resolvedEntity.Name
: null;
entities.Add(((int) uid, entityName));
if (_entityManager.TryGetComponent(uid, out ActorComponent? actor))
{
players.Add(actor.PlayerSession.UserId.UserId);
}
}
return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players, entities);
}
}

View File

@@ -1,19 +1,14 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Server.Administration.Logs.Converters;
using Content.Server.Database; using Content.Server.Database;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.GameTicking.Events; using Content.Server.GameTicking.Events;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Prometheus; using Prometheus;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared; using Robust.Shared;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
@@ -23,7 +18,7 @@ using Robust.Shared.Reflection;
namespace Content.Server.Administration.Logs; namespace Content.Server.Administration.Logs;
public class AdminLogSystem : SharedAdminLogSystem public partial class AdminLogSystem : SharedAdminLogSystem
{ {
[Dependency] private readonly IConfigurationManager _configuration = default!; [Dependency] private readonly IConfigurationManager _configuration = default!;
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
@@ -52,11 +47,8 @@ public class AdminLogSystem : SharedAdminLogSystem
"admin_logs_sent", "admin_logs_sent",
"Amount of logs sent to the database in a round."); "Amount of logs sent to the database in a round.");
private static readonly JsonNamingPolicy NamingPolicy = JsonNamingPolicy.CamelCase;
// Init only // Init only
private ISawmill _sawmill = default!; private ISawmill _sawmill = default!;
private JsonSerializerOptions _jsonOptions = default!;
// CVars // CVars
private bool _metricsEnabled; private bool _metricsEnabled;
@@ -74,19 +66,8 @@ public class AdminLogSystem : SharedAdminLogSystem
base.Initialize(); base.Initialize();
_sawmill = _logManager.GetSawmill(SawmillId); _sawmill = _logManager.GetSawmill(SawmillId);
_jsonOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = NamingPolicy
};
foreach (var converter in _reflection.FindTypesWithAttribute<AdminLogConverterAttribute>()) InitializeJson();
{
var instance = _typeFactory.CreateInstance<JsonConverter>(converter);
_jsonOptions.Converters.Add(instance);
}
var converterNames = _jsonOptions.Converters.Select(converter => converter.GetType().Name);
_sawmill.Info($"Admin log converters found: {string.Join(" ", converterNames)}");
_configuration.OnValueChanged(CVars.MetricsEnabled, _configuration.OnValueChanged(CVars.MetricsEnabled,
value => _metricsEnabled = value, true); value => _metricsEnabled = value, true);
@@ -171,48 +152,6 @@ public class AdminLogSystem : SharedAdminLogSystem
} }
} }
public (JsonDocument json, List<Guid> players, List<(int id, string? name)> entities) ToJson(
Dictionary<string, object?> properties)
{
var entities = new List<(int id, string? name)>();
var players = new List<Guid>();
var parsed = new Dictionary<string, object?>();
foreach (var key in properties.Keys)
{
var value = properties[key];
var parsedKey = NamingPolicy.ConvertName(key);
parsed.Add(parsedKey, value);
EntityUid? entityId = properties[key] switch
{
EntityUid id => id,
IEntity entity => entity.Uid,
IPlayerSession {AttachedEntityUid: { }} session => session.AttachedEntityUid.Value,
IComponent component => component.OwnerUid,
_ => null
};
if (entityId is not { } uid)
{
continue;
}
var entityName = _entityManager.TryGetEntity(uid, out var resolvedEntity)
? resolvedEntity.Name
: null;
entities.Add(((int) uid, entityName));
if (_entityManager.TryGetComponent(uid, out ActorComponent? actor))
{
players.Add(actor.PlayerSession.UserId.UserId);
}
}
return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players, entities);
}
private async void Add(LogType type, LogImpact impact, string message, JsonDocument json, List<Guid> players, List<(int id, string? name)> entities) private async void Add(LogType type, LogImpact impact, string message, JsonDocument json, List<Guid> players, List<(int id, string? name)> entities)
{ {
var log = new AdminLog var log = new AdminLog

View File

@@ -0,0 +1,33 @@
using System.Text.Json;
using Robust.Server.Player;
namespace Content.Server.Administration.Logs.Converters;
[AdminLogConverter]
public class PlayerSessionConverter : AdminLogConverter<SerializablePlayer>
{
public override void Write(Utf8JsonWriter writer, SerializablePlayer value, JsonSerializerOptions options)
{
writer.WriteStartObject();
if (value.Player.AttachedEntity != null)
{
writer.WriteNumber("id", (int) value.Player.AttachedEntity.Uid);
writer.WriteString("name", value.Player.AttachedEntity.Name);
}
writer.WriteString("player", value.Player.UserId.UserId);
writer.WriteEndObject();
}
}
public readonly struct SerializablePlayer
{
public readonly IPlayerSession Player;
public SerializablePlayer(IPlayerSession player)
{
Player = player;
}
}

View File

@@ -10,7 +10,7 @@ public enum LogType
Slip = 4, Slip = 4,
EventAnnounced = 5, EventAnnounced = 5,
EventStarted = 6, EventStarted = 6,
EventRan = 6, EventRan = 16,
EventStopped = 7, EventStopped = 7,
ShuttleCalled = 8, ShuttleCalled = 8,
ShuttleRecalled = 9, ShuttleRecalled = 9,

View File

@@ -100,7 +100,7 @@ namespace Content.Shared.Slippery
PlaySound(component); PlaySound(component);
_adminLog.Add(LogType.Slip, $"{component.Owner} slipped on collision with {otherBody.Owner}"); _adminLog.Add(LogType.Slip, LogImpact.Low, $"{component.Owner} slipped on collision with {otherBody.Owner}");
return true; return true;
} }