diff --git a/Content.Server/Actions/Actions/DisarmAction.cs b/Content.Server/Actions/Actions/DisarmAction.cs index b88de1de28..dbbfd9822a 100644 --- a/Content.Server/Actions/Actions/DisarmAction.cs +++ b/Content.Server/Actions/Actions/DisarmAction.cs @@ -22,7 +22,9 @@ using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; using System; using System.Linq; +using Content.Server.Administration.Logs; using Content.Server.Popups; +using Content.Shared.Administration.Logs; using Content.Shared.Popups; namespace Content.Server.Actions.Actions @@ -94,6 +96,8 @@ namespace Content.Server.Actions.Actions IoCManager.Resolve().EventBus.RaiseLocalEvent(args.Target.Uid, eventArgs); + EntitySystem.Get().Add(LogType.DisarmedAction, LogImpact.Low, $"{args.Performer:performer} used disarm on {args.Target:target}"); + // Check if the event has been handled, and if so, do nothing else! if (eventArgs.Handled) return; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs index d9a59f2c4a..99e035f0c3 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs @@ -66,6 +66,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems if (environment is not null) _atmosphereSystem.Merge(environment, canister.Air); + _adminLogSystem.Add(LogType.CanisterPurged, LogImpact.Medium, $"Canister {uid} purged its contents of {canister.Air} into the environment."); canister.Air.Clear(); } @@ -132,6 +133,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems if (container.ContainedEntities.Count == 0) return; + _adminLogSystem.Add(LogType.CanisterTankEjected, LogImpact.Medium, $"Player {args.Session.AttachedEntity:player} ejected tank {container.ContainedEntities[0]:tank} from {uid}"); container.Remove(container.ContainedEntities[0]); } @@ -142,7 +144,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems var pressure = Math.Clamp(args.Pressure, canister.MinReleasePressure, canister.MaxReleasePressure); - _adminLogSystem.Add(LogType.CanisterPressure, LogImpact.Medium, $"{(args.Session as IPlayerSession):player} set the release pressure on {uid} to {args.Pressure:valveState}"); + _adminLogSystem.Add(LogType.CanisterPressure, LogImpact.Medium, $"{args.Session.AttachedEntity:player} set the release pressure on {uid} to {args.Pressure}"); canister.ReleasePressure = pressure; DirtyUI(uid, canister); @@ -153,7 +155,12 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems if (!CheckInteract(args.Session)) return; - _adminLogSystem.Add(LogType.CanisterValve, LogImpact.High, $"{(args.Session as IPlayerSession):player} set the valve on {uid} to {args.Valve:valveState}"); + var impact = LogImpact.High; + if (EntityManager.TryGetComponent(uid, out ContainerManagerComponent containerManager) + && containerManager.TryGetContainer(canister.ContainerName, out var container)) + impact = container.ContainedEntities.Count != 0 ? LogImpact.Medium : LogImpact.High; + + _adminLogSystem.Add(LogType.CanisterValve, impact, $"{args.Session.AttachedEntity:player} set the valve on {uid} to {args.Valve:valveState}"); canister.ReleaseValve = args.Valve; DirtyUI(uid, canister); @@ -275,6 +282,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems if (!hands.Drop(args.Used, container)) return; + _adminLogSystem.Add(LogType.CanisterTankInserted, LogImpact.Medium, $"Player {args.User:player} inserted tank {container.ContainedEntities[0]} into {uid}"); + args.Handled = true; } diff --git a/Content.Server/Crayon/CrayonComponent.cs b/Content.Server/Crayon/CrayonComponent.cs index 43cddd47cf..90ee7f161a 100644 --- a/Content.Server/Crayon/CrayonComponent.cs +++ b/Content.Server/Crayon/CrayonComponent.cs @@ -1,6 +1,8 @@ using System.Linq; using System.Threading.Tasks; +using Content.Server.Administration.Logs; using Content.Server.UserInterface; +using Content.Shared.Administration.Logs; using Content.Shared.Audio; using Content.Shared.Crayon; using Content.Shared.Interaction; @@ -141,6 +143,7 @@ namespace Content.Server.Crayon // Decrease "Ammo" Charges--; Dirty(); + EntitySystem.Get().Add(LogType.CrayonDraw, $"{eventArgs.User:player} drew a {_color:color} {SelectedState}"); return true; } diff --git a/Content.Server/Interaction/InteractionSystem.cs b/Content.Server/Interaction/InteractionSystem.cs index 5c304801b3..4927934494 100644 --- a/Content.Server/Interaction/InteractionSystem.cs +++ b/Content.Server/Interaction/InteractionSystem.cs @@ -2,11 +2,13 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; +using Content.Server.Administration.Logs; using Content.Server.CombatMode; using Content.Server.Hands.Components; using Content.Server.Items; using Content.Server.Pulling; using Content.Shared.ActionBlocker; +using Content.Shared.Administration.Logs; using Content.Shared.DragDrop; using Content.Shared.Input; using Content.Shared.Interaction; @@ -39,6 +41,7 @@ namespace Content.Server.Interaction [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; [Dependency] private readonly PullingSystem _pullSystem = default!; [Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!; + [Dependency] private readonly AdminLogSystem _adminLogSystem = default!; public override void Initialize() { @@ -376,6 +379,7 @@ namespace Content.Server.Interaction // all interactions should only happen when in range / unobstructed, so no range check is needed var message = new InteractHandEvent(user, target); RaiseLocalEvent(target.Uid, message); + _adminLogSystem.Add(LogType.InteractHand, LogImpact.Low, $"{user} interacted with {target}"); if (message.Handled) return; @@ -469,7 +473,10 @@ namespace Content.Server.Interaction RaiseLocalEvent(item.Uid, ev, false); if (ev.Handled) + { + _adminLogSystem.Add(LogType.AttackArmedWide, LogImpact.Medium, $"{user} wide attacked with {item} at {coordinates}"); return; + } } else { @@ -477,7 +484,20 @@ namespace Content.Server.Interaction RaiseLocalEvent(item.Uid, ev, false); if (ev.Handled) + { + if (targetEnt != null) + { + _adminLogSystem.Add(LogType.AttackArmedClick, LogImpact.Medium, + $"{user} attacked {targetEnt} with {item} at {coordinates}"); + } + else + { + _adminLogSystem.Add(LogType.AttackArmedClick, LogImpact.Medium, + $"{user} attacked with {item} at {coordinates}"); + } + return; + } } } else if (!wideAttack && @@ -493,9 +513,30 @@ namespace Content.Server.Interaction // TODO: Make this saner? // Attempt to do unarmed combat. We don't check for handled just because at this point it doesn't matter. if (wideAttack) - RaiseLocalEvent(user.Uid, new WideAttackEvent(user, user, coordinates), false); + { + var ev = new WideAttackEvent(user, user, coordinates); + RaiseLocalEvent(user.Uid, ev, false); + if (ev.Handled) + _adminLogSystem.Add(LogType.AttackUnarmedWide, $"{user} wide attacked at {coordinates}"); + } else - RaiseLocalEvent(user.Uid, new ClickAttackEvent(user, user, coordinates, targetUid), false); + { + var ev = new ClickAttackEvent(user, user, coordinates, targetUid); + RaiseLocalEvent(user.Uid, ev, false); + if (ev.Handled) + { + if (targetEnt != null) + { + _adminLogSystem.Add(LogType.AttackUnarmedClick, LogImpact.Medium, + $"{user} attacked {targetEnt} at {coordinates}"); + } + else + { + _adminLogSystem.Add(LogType.AttackUnarmedClick, LogImpact.Medium, + $"{user} attacked at {coordinates}"); + } + } + } } } } diff --git a/Content.Server/Projectiles/ProjectileSystem.cs b/Content.Server/Projectiles/ProjectileSystem.cs index 70d8f7ed8c..982f178c2c 100644 --- a/Content.Server/Projectiles/ProjectileSystem.cs +++ b/Content.Server/Projectiles/ProjectileSystem.cs @@ -1,5 +1,7 @@ +using Content.Server.Administration.Logs; using Content.Server.Camera; using Content.Server.Projectiles.Components; +using Content.Shared.Administration.Logs; using Content.Shared.Body.Components; using Content.Shared.Damage; using JetBrains.Annotations; @@ -15,6 +17,7 @@ namespace Content.Server.Projectiles internal sealed class ProjectileSystem : EntitySystem { [Dependency] private readonly DamageableSystem _damageableSystem = default!; + [Dependency] private readonly AdminLogSystem _adminLogSystem = default!; public override void Initialize() { @@ -50,8 +53,11 @@ namespace Content.Server.Projectiles if (!otherEntity.Deleted) { - _damageableSystem.TryChangeDamage(otherEntity.Uid, component.Damage); + var dmg = _damageableSystem.TryChangeDamage(otherEntity.Uid, component.Damage); component.DamagedEntity = true; + + if (dmg is not null && EntityManager.TryGetEntity(component.Shooter, out var shooter)) + _adminLogSystem.Add(LogType.BulletHit, LogImpact.Low, $"Bullet shot by {shooter} hit {otherEntity}"); // "DamagedEntity" is misleading. Hit entity may be more accurate, as the damage may have been resisted // by resistance sets. } diff --git a/Content.Server/Stunnable/StunSystem.cs b/Content.Server/Stunnable/StunSystem.cs index 62a9231c27..f03084fc1a 100644 --- a/Content.Server/Stunnable/StunSystem.cs +++ b/Content.Server/Stunnable/StunSystem.cs @@ -1,6 +1,8 @@ using System; using Content.Server.Act; +using Content.Server.Administration.Logs; using Content.Server.Popups; +using Content.Shared.Administration.Logs; using Content.Shared.Audio; using Content.Shared.Popups; using Content.Shared.StatusEffect; @@ -17,6 +19,7 @@ namespace Content.Server.Stunnable public sealed class StunSystem : SharedStunSystem { [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly AdminLogSystem _adminLogSystem = default!; public override void Initialize() { @@ -49,6 +52,8 @@ namespace Content.Server.Stunnable } } + _adminLogSystem.Add(LogType.DisarmedKnockdown, LogImpact.Medium, $"{args.Source:performer} knocked down {args.Target:target}"); + args.Handled = true; } } diff --git a/Content.Shared/Administration/Logs/LogType.cs b/Content.Shared/Administration/Logs/LogType.cs index dfd9a36492..c9b22a2e7a 100644 --- a/Content.Shared/Administration/Logs/LogType.cs +++ b/Content.Shared/Administration/Logs/LogType.cs @@ -20,4 +20,22 @@ public enum LogType ReagentEffect = 18, CanisterValve = 20, CanisterPressure = 21, + CanisterPurged = 22, + CanisterTankEjected = 23, + CanisterTankInserted = 24, + DisarmedAction = 25, + DisarmedKnockdown = 26, + AttackArmedClick = 27, + AttackArmedWide = 28, + AttackUnarmedClick = 29, + AttackUnarmedWide = 30, + InteractHand = 31, + InteractActivate = 32, + Throw = 33, + Landed = 34, + ThrowHit = 35, + Pickup = 36, + Drop = 37, + BulletHit = 38, + CrayonDraw = 39, } diff --git a/Content.Shared/Hands/Components/SharedHandsComponent.cs b/Content.Shared/Hands/Components/SharedHandsComponent.cs index 45b8d984cc..3b39b7b280 100644 --- a/Content.Shared/Hands/Components/SharedHandsComponent.cs +++ b/Content.Shared/Hands/Components/SharedHandsComponent.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.ActionBlocker; +using Content.Shared.Administration.Logs; using Content.Shared.Interaction; using Content.Shared.Item; using Robust.Shared.Containers; @@ -668,6 +669,7 @@ namespace Content.Shared.Hands.Components HandlePickupAnimation(entity); PutEntityIntoHand(hand, entity); + EntitySystem.Get().Add(LogType.Pickup, LogImpact.Low, $"{Owner} picked up {entity}"); return true; } diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index fbdaf41e0a..79c47c13ba 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using System.Threading.Tasks; using Content.Shared.ActionBlocker; +using Content.Shared.Administration.Logs; using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Inventory; @@ -34,6 +35,7 @@ namespace Content.Shared.Interaction [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; [Dependency] private readonly SharedVerbSystem _verbSystem = default!; + [Dependency] private readonly SharedAdminLogSystem _adminLogSystem = default!; public const float InteractionRange = 2; public const float InteractionRangeSquared = InteractionRange * InteractionRange; @@ -454,13 +456,17 @@ namespace Content.Shared.Interaction var activateMsg = new ActivateInWorldEvent(user, used); RaiseLocalEvent(used.Uid, activateMsg); if (activateMsg.Handled) + { + _adminLogSystem.Add(LogType.InteractActivate, LogImpact.Low, $"{user} activated {used}"); return; + } if (!used.TryGetComponent(out IActivate? activateComp)) return; var activateEventArgs = new ActivateEventArgs(user, used); activateComp.Activate(activateEventArgs); + _adminLogSystem.Add(LogType.InteractActivate, LogImpact.Low, $"{user} activated {used}"); // No way to check success. } #endregion @@ -558,7 +564,10 @@ namespace Content.Shared.Interaction var throwMsg = new ThrownEvent(user, thrown); RaiseLocalEvent(thrown.Uid, throwMsg); if (throwMsg.Handled) + { + _adminLogSystem.Add(LogType.Throw, LogImpact.Low,$"{user} threw {thrown}"); return; + } var comps = thrown.GetAllComponents().ToList(); var args = new ThrownEventArgs(user); @@ -568,6 +577,7 @@ namespace Content.Shared.Interaction { comp.Thrown(args); } + _adminLogSystem.Add(LogType.Throw, LogImpact.Low,$"{user} threw {thrown}"); } #endregion @@ -675,7 +685,10 @@ namespace Content.Shared.Interaction var dropMsg = new DroppedEvent(user.Uid, item.Uid); RaiseLocalEvent(item.Uid, dropMsg); if (dropMsg.Handled) + { + _adminLogSystem.Add(LogType.Drop, LogImpact.Low, $"{user} dropped {item}"); return; + } item.Transform.LocalRotation = Angle.Zero; @@ -686,6 +699,7 @@ namespace Content.Shared.Interaction { comp.Dropped(new DroppedEventArgs(user)); } + _adminLogSystem.Add(LogType.Drop, LogImpact.Low, $"{user} dropped {item}"); } #endregion diff --git a/Content.Shared/Throwing/ThrownItemSystem.cs b/Content.Shared/Throwing/ThrownItemSystem.cs index e6ed143342..a750fe4fa0 100644 --- a/Content.Shared/Throwing/ThrownItemSystem.cs +++ b/Content.Shared/Throwing/ThrownItemSystem.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using Content.Shared.Administration.Logs; using Content.Shared.CCVar; using Content.Shared.Hands.Components; using Content.Shared.Physics; @@ -23,6 +24,7 @@ namespace Content.Shared.Throwing { [Dependency] private readonly SharedBroadphaseSystem _broadphaseSystem = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly SharedAdminLogSystem _adminLogSystem = default!; private const string ThrowingFixture = "throw-fixture"; @@ -128,6 +130,11 @@ namespace Content.Shared.Throwing var landMsg = new LandEvent {User = thrownItem.Thrower?.Uid}; RaiseLocalEvent(landing.Uid, landMsg, false); + + // Assume it's uninteresting if it has no thrower. For now anyway. + if (thrownItem.Thrower is not null) + _adminLogSystem.Add(LogType.Landed, LogImpact.Low, $"{landing} thrown by {thrownItem.Thrower:thrower} landed."); + } /// @@ -138,6 +145,8 @@ namespace Content.Shared.Throwing // TODO: Just pass in the bodies directly RaiseLocalEvent(target.Owner.Uid, new ThrowHitByEvent(user, thrown.Owner, target.Owner)); RaiseLocalEvent(thrown.Owner.Uid, new ThrowDoHitEvent(user, thrown.Owner, target.Owner)); + if (user is not null) + _adminLogSystem.Add(LogType.ThrowHit, LogImpact.Low, $"{thrown.Owner:thrown} thrown by {user:thrower} hit {target.Owner:target}."); } } }