Adds even more important Admin Logging (#10268)

This commit is contained in:
Júlio César Ueti
2022-08-07 20:21:56 -03:00
committed by GitHub
parent a2d8e96a53
commit ee969c9799
15 changed files with 147 additions and 49 deletions

View File

@@ -1,8 +1,11 @@
using System.Linq;
using Content.Server.Access.Systems;
using Content.Server.Administration.Logs;
using Content.Server.UserInterface;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Database;
using Robust.Server.GameObjects;
namespace Content.Server.Access.Components
@@ -12,6 +15,7 @@ namespace Content.Server.Access.Components
public sealed class IdCardConsoleComponent : SharedIdCardConsoleComponent
{
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(IdCardConsoleUiKey.Key);
@@ -26,6 +30,7 @@ namespace Content.Server.Access.Components
{
UserInterface.OnReceiveMessage += OnUiReceiveMessage;
}
}
private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj)
@@ -38,7 +43,7 @@ namespace Content.Server.Access.Components
switch (obj.Message)
{
case WriteToTargetIdMessage msg:
TryWriteToTargetId(msg.FullName, msg.JobTitle, msg.AccessList);
TryWriteToTargetId(msg.FullName, msg.JobTitle, msg.AccessList, player);
UpdateUserInterface();
break;
}
@@ -60,17 +65,17 @@ namespace Content.Server.Access.Components
}
/// <summary>
/// Called when the "Submit" button in the UI gets pressed.
/// Called whenever an access button is pressed, adding or removing that access from the target ID card.
/// Writes data passed from the UI into the ID stored in <see cref="TargetIdSlot"/>, if present.
/// </summary>
private void TryWriteToTargetId(string newFullName, string newJobTitle, List<string> newAccessList)
private void TryWriteToTargetId(string newFullName, string newJobTitle, List<string> newAccessList, EntityUid player)
{
if (TargetIdSlot.Item is not {Valid: true} targetIdEntity || !PrivilegedIdIsAuthorized())
return;
var cardSystem = EntitySystem.Get<IdCardSystem>();
cardSystem.TryChangeFullName(targetIdEntity, newFullName);
cardSystem.TryChangeJobTitle(targetIdEntity, newJobTitle);
cardSystem.TryChangeFullName(targetIdEntity, newFullName, player: player);
cardSystem.TryChangeJobTitle(targetIdEntity, newJobTitle, player: player);
if (!newAccessList.TrueForAll(x => AccessLevels.Contains(x)))
{
@@ -80,6 +85,12 @@ namespace Content.Server.Access.Components
var accessSystem = EntitySystem.Get<AccessSystem>();
accessSystem.TrySetTags(targetIdEntity, newAccessList);
/*TODO: ECS IdCardConsoleComponent and then log on card ejection, together with the save.
This current implementation is pretty shit as it logs 27 entries (27 lines) if someone decides to give themselves AA*/
_adminLogger.Add(LogType.Action, LogImpact.Medium,
$"{_entities.ToPrettyString(player):player} has modified {_entities.ToPrettyString(targetIdEntity):entity} with the following accesses: [{string.Join(", ", newAccessList)}]");
}
public void UpdateUserInterface()

View File

@@ -2,11 +2,13 @@ using Content.Shared.Hands.Components;
using Content.Shared.Inventory;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Administration.Logs;
using Content.Server.Kitchen.Components;
using Content.Server.Popups;
using Content.Shared.Access;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Database;
using Content.Shared.PDA;
using Content.Shared.Popups;
using Robust.Shared.Player;
@@ -21,6 +23,7 @@ namespace Content.Server.Access.Systems
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
public override void Initialize()
{
@@ -73,22 +76,39 @@ namespace Content.Server.Access.Systems
}
}
public bool TryChangeJobTitle(EntityUid uid, string jobTitle, IdCardComponent? id = null)
/// <summary>
/// Attempts to change the job title of a card.
/// Returns true/false.
/// </summary>
/// <remarks>
/// If provided with a player's EntityUid to the player parameter, adds the change to the admin logs.
/// </remarks>
public bool TryChangeJobTitle(EntityUid uid, string jobTitle, IdCardComponent? id = null, EntityUid? player = null)
{
if (!Resolve(uid, ref id))
return false;
// TODO: Whenever we get admin logging these should be logged
if (jobTitle.Length > SharedIdCardConsoleComponent.MaxJobTitleLength)
jobTitle = jobTitle[..SharedIdCardConsoleComponent.MaxJobTitleLength];
id.JobTitle = jobTitle;
Dirty(id);
UpdateEntityName(uid, id);
if (player != null)
_adminLogger.Add(LogType.Identity, LogImpact.Low,
$"{ToPrettyString(player.Value):player} has changed the job title of {ToPrettyString(id.Owner):entity} to {jobTitle} ");
return true;
}
public bool TryChangeFullName(EntityUid uid, string fullName, IdCardComponent? id = null)
/// <summary>
/// Attempts to change the full name of a card.
/// Returns true/false.
/// </summary>
/// <remarks>
/// If provided with a player's EntityUid to the player parameter, adds the change to the admin logs.
/// </remarks>
public bool TryChangeFullName(EntityUid uid, string fullName, IdCardComponent? id = null, EntityUid? player = null)
{
if (!Resolve(uid, ref id))
return false;
@@ -99,6 +119,10 @@ namespace Content.Server.Access.Systems
id.FullName = fullName;
Dirty(id);
UpdateEntityName(uid, id);
if (player != null)
_adminLogger.Add(LogType.Identity, LogImpact.Low,
$"{ToPrettyString(player.Value):player} has changed the name of {ToPrettyString(id.Owner):entity} to {fullName} ");
return true;
}

View File

@@ -131,7 +131,15 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
&& containerManager.TryGetContainer(canister.ContainerName, out var container))
impact = container.ContainedEntities.Count != 0 ? LogImpact.Medium : LogImpact.High;
_adminLogger.Add(LogType.CanisterValve, impact, $"{ToPrettyString(args.Session.AttachedEntity.GetValueOrDefault()):player} set the valve on {ToPrettyString(uid):canister} to {args.Valve:valveState}");
var containedGasDict = new Dictionary<Gas, float>();
var containedGasArray = Gas.GetValues(typeof(Gas));
for (int i = 0; i < containedGasArray.Length; i++)
{
containedGasDict.Add((Gas)i, canister.Air.Moles[i]);
}
_adminLogger.Add(LogType.CanisterValve, impact, $"{ToPrettyString(args.Session.AttachedEntity.GetValueOrDefault()):player} set the valve on {ToPrettyString(uid):canister} to {args.Valve:valveState} while it contained [{string.Join(", ", containedGasDict)}]");
canister.ReleaseValve = args.Valve;
DirtyUI(uid, canister);

View File

@@ -6,6 +6,7 @@ using Content.Server.Administration.Managers;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Ghost.Components;
using Content.Server.Mind.Components;
using Content.Server.Players;
using Content.Server.Popups;
using Content.Server.Radio.EntitySystems;
@@ -18,6 +19,7 @@ using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.IdentityManagement;
using Content.Shared.Inventory;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Audio;
using Robust.Shared.Configuration;
@@ -268,6 +270,10 @@ public sealed partial class ChatSystem : SharedChatSystem
var ev = new EntitySpokeEvent(message);
RaiseLocalEvent(source, ev);
// To avoid logging any messages sent by entities that are not players, like vendors, cloning, etc.
if (!TryComp(source, out ActorComponent? mind))
return;
if (originalMessage == message)
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Say from {ToPrettyString(source):user}: {originalMessage}.");
else
@@ -362,18 +368,18 @@ public sealed partial class ChatSystem : SharedChatSystem
messageWrap = Loc.GetString("chat-manager-send-admin-dead-chat-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")),
("userName", player.ConnectedClient.UserName));
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Dead chat from {player:Player}: {message}");
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Admin dead chat from {player:Player}: {message}");
}
else
{
messageWrap = Loc.GetString("chat-manager-send-dead-chat-wrap-message",
("deadChannelName", Loc.GetString("chat-manager-dead-channel-name")),
("playerName", (playerName)));
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Admin dead chat from {player:Player}: {message}");
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Dead chat from {player:Player}: {message}");
}
_chatManager.ChatMessageToMany(ChatChannel.Dead, message, messageWrap, source, hideChat, clients.ToList());
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Dead chat from {player:Player}: {message}");
}
#endregion

View File

@@ -1,9 +1,11 @@
using System.Linq;
using Content.Server.Administration.Logs;
using Content.Server.Chemistry.EntitySystems;
using Content.Server.Power.Components;
using Content.Server.UserInterface;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Dispenser;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
@@ -29,6 +31,7 @@ namespace Content.Server.Chemistry.Components
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[ViewVariables] [DataField("pack", customTypeSerializer:typeof(PrototypeIdSerializer<ReagentDispenserInventoryPrototype>))] private string _packPrototypeId = "";
@@ -171,8 +174,11 @@ namespace Content.Server.Chemistry.Components
if (BeakerSlot.HasItem)
{
TryDispense(msg.DispenseIndex);
// Ew
if (BeakerSlot.Item != null)
_adminLogger.Add(LogType.ChemicalReaction, LogImpact.Medium,
$"{_entities.ToPrettyString(obj.Session.AttachedEntity.Value):player} dispensed {_dispenseAmount}u of {Inventory[msg.DispenseIndex].ID} into {_entities.ToPrettyString(BeakerSlot.Item.Value):entity}");
}
Logger.Info($"User {obj.Session.UserId.UserId} ({obj.Session.Name}) dispensed {_dispenseAmount}u of {Inventory[msg.DispenseIndex].ID}");
break;
default:

View File

@@ -1,9 +1,11 @@
using Content.Server.Administration.Logs;
using Content.Shared.Verbs;
using Content.Server.Chemistry.Components;
using Content.Server.Chemistry.Components.SolutionManager;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Content.Shared.Chemistry.Components;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Interaction;
using Content.Shared.Popups;
@@ -14,6 +16,7 @@ namespace Content.Server.Chemistry.EntitySystems
public sealed class SolutionTransferSystem : EntitySystem
{
[Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
/// <summary>
/// Default transfer amounts for the set-transfer verb.
@@ -181,6 +184,9 @@ namespace Content.Server.Chemistry.EntitySystems
var solution = solutionSystem.Drain(sourceEntity, source, actualAmount);
solutionSystem.Refill(targetEntity, target, solution);
_adminLogger.Add(LogType.Action, LogImpact.Medium,
$"{EntityManager.ToPrettyString(user):player} transferred {string.Join(", ", solution.Contents)} to {EntityManager.ToPrettyString(targetEntity):entity}, which now contains {string.Join(", ", target.Contents)}");
return actualAmount;
}
}

View File

@@ -1,6 +1,7 @@
using System.Globalization;
using System.Linq;
using Content.Server.Access.Systems;
using Content.Server.Administration.Logs;
using Content.Server.AlertLevel;
using Content.Server.Chat;
using Content.Server.Chat.Systems;
@@ -13,6 +14,7 @@ using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.CCVar;
using Content.Shared.Communications;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Popups;
using Robust.Server.GameObjects;
@@ -33,6 +35,7 @@ namespace Content.Server.Communications
[Dependency] private readonly ShuttleSystem _shuttle = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
private const int MaxMessageLength = 256;
private const float UIUpdateInterval = 5.0f;
@@ -251,9 +254,16 @@ namespace Content.Server.Communications
if (comp.AnnounceGlobal)
{
_chatSystem.DispatchGlobalAnnouncement(msg, title, announcementSound: comp.AnnouncementSound, colorOverride: comp.AnnouncementColor);
if (message.Session.AttachedEntity != null)
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(message.Session.AttachedEntity.Value):player} has sent the following global announcement: {msg}");
return;
}
_chatSystem.DispatchStationAnnouncement(uid, msg, title, colorOverride: comp.AnnouncementColor);
if (message.Session.AttachedEntity != null)
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(message.Session.AttachedEntity.Value):player} has sent the following station announcement: {msg}");
}
private void OnCallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleCallEmergencyShuttleMessage message)
@@ -266,6 +276,7 @@ namespace Content.Server.Communications
return;
}
_roundEndSystem.RequestRoundEnd(uid);
_adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(mob):player} has called the shuttle.");
}
private void OnRecallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleRecallEmergencyShuttleMessage message)
@@ -279,6 +290,7 @@ namespace Content.Server.Communications
}
_roundEndSystem.CancelRoundEndCountdown(uid);
_adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(mob):player} has recalled the shuttle.");
}
}
}

View File

@@ -1,8 +1,10 @@
using Content.Server.Administration.Logs;
using Content.Server.Construction.Components;
using Content.Server.DoAfter;
using Content.Shared.Construction;
using Content.Shared.Construction.EntitySystems;
using Content.Shared.Construction.Steps;
using Content.Shared.Database;
using Content.Shared.Interaction;
using Robust.Shared.Containers;
@@ -10,6 +12,8 @@ namespace Content.Server.Construction
{
public sealed partial class ConstructionSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
private readonly HashSet<EntityUid> _constructionUpdateQueue = new();
private void InitializeInteractions()
@@ -38,7 +42,7 @@ namespace Content.Server.Construction
/// <remarks>When <see cref="validation"/> is true, this method will simply return whether the interaction
/// would be handled by the entity or not. It essentially becomes a pure method that modifies nothing.</remarks>
/// <returns>The result of this interaction with the entity.</returns>
private HandleResult HandleEvent(EntityUid uid, object ev, bool validation, ConstructionComponent? construction = null)
private HandleResult HandleEvent(EntityUid uid, object ev, bool validation, ConstructionComponent? construction = null, InteractUsingEvent? args = null)
{
if (!Resolve(uid, ref construction))
return HandleResult.False;
@@ -160,6 +164,9 @@ namespace Content.Server.Construction
// We change the node now.
ChangeNode(uid, user, edge.Target, true, construction);
if (ev is ConstructionDoAfterComplete event1 && event1.WrappedEvent is InteractUsingEvent event2)
_adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(event2.User):player} changed {ToPrettyString(uid):entity}'s node to {edge.Target}");
}
return HandleResult.True;

View File

@@ -1,9 +1,11 @@
using System.Linq;
using Content.Server.Administration.Logs;
using Content.Server.DoAfter;
using Content.Server.Hands.Components;
using Content.Shared.ActionBlocker;
using Content.Shared.Alert;
using Content.Shared.Cuffs.Components;
using Content.Shared.Database;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Popups;
@@ -25,6 +27,7 @@ namespace Content.Server.Cuffs.Components
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
[Dependency] private readonly IComponentFactory _componentFactory = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
/// <summary>
/// How many of this entity's hands are currently cuffed.
@@ -280,6 +283,16 @@ namespace Content.Server.Cuffs.Components
{
user.PopupMessage(Owner, Loc.GetString("cuffable-component-remove-cuffs-by-other-success-message", ("otherName", user)));
}
if (user == Owner)
{
_adminLogger.Add(LogType.Action, LogImpact.Medium, $"{_entMan.ToPrettyString(user):player} has successfully uncuffed themselves");
}
else
{
_adminLogger.Add(LogType.Action, LogImpact.Medium, $"{_entMan.ToPrettyString(user):player} has successfully uncuffed {_entMan.ToPrettyString(Owner):player}");
}
}
else
{

View File

@@ -1,8 +1,10 @@
using System.Threading.Tasks;
using Content.Server.Administration.Components;
using Content.Server.Administration.Logs;
using Content.Server.DoAfter;
using Content.Server.Hands.Components;
using Content.Shared.Cuffs.Components;
using Content.Shared.Database;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
@@ -16,6 +18,7 @@ namespace Content.Server.Cuffs.Components
public sealed class HandcuffComponent : SharedHandcuffComponent
{
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
/// <summary>
/// The time it takes to apply a <see cref="CuffedComponent"/> to an entity.
@@ -173,11 +176,13 @@ namespace Content.Server.Cuffs.Components
if (target == user)
{
user.PopupMessage(Loc.GetString("handcuff-component-cuff-self-success-message"));
_adminLogger.Add(LogType.Action, LogImpact.Medium, $"{_entities.ToPrettyString(user):player} has cuffed himself");
}
else
{
user.PopupMessage(Loc.GetString("handcuff-component-cuff-other-success-message",("otherName", target)));
target.PopupMessage(Loc.GetString("handcuff-component-cuff-by-other-success-message", ("otherName", user)));
_adminLogger.Add(LogType.Action, LogImpact.Medium, $"{_entities.ToPrettyString(user):player} has cuffed {_entities.ToPrettyString(target):player}");
}
}
}

View File

@@ -8,7 +8,6 @@ using Content.Shared.Popups;
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Shared.Player;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Robust.Shared.Audio;

View File

@@ -1,4 +1,6 @@
using System.Linq;
using Content.Server.Administration.Logs;
using Content.Server.Chemistry.Components.SolutionManager;
using Content.Server.Explosion.Components;
using Content.Server.Flash;
using Content.Server.Flash.Components;
@@ -13,7 +15,10 @@ using Content.Shared.Trigger;
using Content.Shared.Database;
using Content.Shared.Explosion;
using Content.Shared.Interaction;
using Content.Shared.Payload.Components;
using Content.Shared.StepTrigger.Systems;
using Robust.Server.Containers;
using Robust.Shared.Containers;
namespace Content.Server.Explosion.EntitySystems
{
@@ -39,7 +44,8 @@ namespace Content.Server.Explosion.EntitySystems
[Dependency] private readonly FixtureSystem _fixtures = default!;
[Dependency] private readonly FlashSystem _flashSystem = default!;
[Dependency] private readonly SharedBroadphaseSystem _broadphase = default!;
[Dependency] private readonly IAdminLogManager _adminLogger= default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
public override void Initialize()
{
@@ -118,8 +124,24 @@ namespace Content.Server.Explosion.EntitySystems
if (user != null)
{
_adminLogger.Add(LogType.Trigger,
$"{ToPrettyString(user.Value):user} started a {delay} second timer trigger on entity {ToPrettyString(uid):timer}");
// Check if entity is bomb/mod. grenade/etc
if (_container.TryGetContainer(uid, "payload", out IContainer? container) &&
TryComp(container.ContainedEntities.First(), out ChemicalPayloadComponent? chemicalPayloadComponent))
{
// If a beaker is missing, the entity won't explode, so no reason to log it
if (!TryComp(chemicalPayloadComponent?.BeakerSlotA.Item, out SolutionContainerManagerComponent? beakerA) ||
!TryComp(chemicalPayloadComponent?.BeakerSlotB.Item, out SolutionContainerManagerComponent? beakerB))
return;
_adminLogger.Add(LogType.Trigger,
$"{ToPrettyString(user.Value):user} started a {delay} second timer trigger on entity {ToPrettyString(uid):timer}, which contains [{string.Join(", ", beakerA.Solutions.Values.First())}] in one beaker and [{string.Join(", ", beakerB.Solutions.Values.First())}] in the other.");
}
else
{
_adminLogger.Add(LogType.Trigger,
$"{ToPrettyString(user.Value):user} started a {delay} second timer trigger on entity {ToPrettyString(uid):timer}");
}
}
else
{

View File

@@ -225,10 +225,7 @@ namespace Content.Server.Interaction
RaiseLocalEvent(item.Value, ev, false);
if (ev.Handled)
{
_adminLogger.Add(LogType.AttackArmedWide, LogImpact.Low, $"{ToPrettyString(user):user} wide attacked with {ToPrettyString(item.Value):used} at {coordinates}");
return;
}
}
else
{
@@ -236,20 +233,7 @@ namespace Content.Server.Interaction
RaiseLocalEvent(item.Value, ev, false);
if (ev.Handled)
{
if (target != null)
{
_adminLogger.Add(LogType.AttackArmedClick, LogImpact.Low,
$"{ToPrettyString(user):user} attacked {ToPrettyString(target.Value):target} with {ToPrettyString(item.Value):used} at {coordinates}");
}
else
{
_adminLogger.Add(LogType.AttackArmedClick, LogImpact.Low,
$"{ToPrettyString(user):user} attacked with {ToPrettyString(item.Value):used} at {coordinates}");
}
return;
}
}
}
else if (!wideAttack && target != null && HasComp<ItemComponent>(target.Value))
@@ -279,19 +263,6 @@ namespace Content.Server.Interaction
{
var ev = new ClickAttackEvent(used, user, coordinates, target);
RaiseLocalEvent(used, ev, false);
if (ev.Handled)
{
if (target != null)
{
_adminLogger.Add(LogType.AttackUnarmedClick, LogImpact.Low,
$"{ToPrettyString(user):user} attacked {ToPrettyString(target.Value):target} at {coordinates}");
}
else
{
_adminLogger.Add(LogType.AttackUnarmedClick, LogImpact.Low,
$"{ToPrettyString(user):user} attacked at {coordinates}");
}
}
}
}
}

View File

@@ -1,5 +1,7 @@
using Content.Server.Administration.Logs;
using Content.Server.Popups;
using Content.Server.UserInterface;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
@@ -16,6 +18,8 @@ namespace Content.Server.Paper
[Dependency] private readonly TagSystem _tagSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
public override void Initialize()
{
base.Initialize();
@@ -77,7 +81,7 @@ namespace Content.Server.Paper
if (_tagSystem.HasTag(args.Used, "Write"))
{
if (!TryComp<ActorComponent>(args.User, out var actor))
return;
return;
paperComp.Mode = PaperAction.Write;
UpdateUserInterface(uid, paperComp);
@@ -110,6 +114,10 @@ namespace Content.Server.Paper
if (TryComp<MetaDataComponent>(uid, out var meta))
meta.EntityDescription = "";
if (args.Session.AttachedEntity != null)
_adminLogger.Add(LogType.Chat, LogImpact.Low,
$"{ToPrettyString(args.Session.AttachedEntity.Value):player} has written on {ToPrettyString(uid):entity} the following text: {args.Text}");
UpdateUserInterface(uid, paperComp);
}