From 43d08100b9374739dff56e031d128ee6709624c1 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Thu, 20 Mar 2025 20:56:51 +0100 Subject: [PATCH] "New player" admin logging improvements (#35961) * Initial commit * Adjust a whoooole bunch of logs * Also spears * Track going crit * Review fix * Review fixes --- .../Access/Systems/AccessOverriderSystem.cs | 2 +- .../Access/Systems/IdCardConsoleSystem.cs | 2 +- Content.Server/Access/Systems/IdCardSystem.cs | 2 +- .../Commands/ChangeCvarCommand.cs | 2 +- .../Administration/Logs/AdminLogManager.cs | 25 ++++++++++ .../Ame/EntitySystems/AmeControllerSystem.cs | 20 ++------ .../Anomaly/Effects/InnerBodyAnomalySystem.cs | 2 +- Content.Server/Botany/SeedPrototype.cs | 13 +++++ .../Botany/Systems/BotanySystem.Seed.cs | 12 +++++ .../Botany/Systems/PlantHolderSystem.cs | 6 +++ .../Clothing/Systems/CursedMaskSystem.cs | 2 +- .../CommunicationsConsoleSystem.cs | 4 +- .../Construction/Completions/AdminLog.cs | 2 +- Content.Server/Decals/DecalSystem.cs | 8 +-- .../Destructible/DestructibleSystem.cs | 15 +++++- .../Thresholds/Behaviors/GibBehavior.cs | 3 ++ .../Behaviors/IThresholdBehavior.cs | 6 ++- .../EntitySystems/ExplosionSystem.cs | 9 ++-- .../EntitySystems/TriggerSystem.Voice.cs | 2 +- .../EntitySystems/KitchenSpikeSystem.cs | 7 ++- .../Materials/MaterialReclaimerSystem.cs | 4 +- .../BiomassReclaimerSystem.cs | 4 +- Content.Server/Mining/MeteorSystem.cs | 2 +- Content.Server/Morgue/CrematoriumSystem.cs | 2 +- .../Nutrition/EntitySystems/DrinkSystem.cs | 2 +- .../Placement/PlacementLoggerSystem.cs | 12 ++--- .../Power/EntitySystems/CableSystem.cs | 2 +- .../Projectiles/ProjectileSystem.cs | 2 +- .../Respawn/SpecialRespawnSystem.cs | 2 +- .../Systems/EmergencyShuttleSystem.Console.cs | 2 +- .../EntitySystems/EventHorizonSystem.cs | 2 +- .../Teleportation/HandTeleporterSystem.cs | 6 +-- Content.Shared.Database/LogImpact.cs | 8 +-- Content.Shared.Database/LogType.cs | 5 ++ Content.Shared/Anomaly/SharedAnomalySystem.cs | 2 +- Content.Shared/CCVar/CCVars.Admin.Logs.cs | 7 +++ Content.Shared/Cuffs/SharedCuffableSystem.cs | 8 +-- .../Systems/MobStateSystem.StateMachine.cs | 8 ++- Content.Shared/Roles/SharedRoleSystem.cs | 4 +- .../Strip/SharedStrippableSystem.cs | 4 +- .../en-US/chat/managers/chat-manager.ftl | 2 +- Resources/Prototypes/Hydroponics/seeds.yml | 4 ++ .../Graphs/furniture/meatspike.yml | 49 ++++++++++--------- .../Construction/Graphs/structures/grille.yml | 3 ++ .../Construction/Graphs/weapons/shiv.yml | 32 ++++++++++++ .../Construction/Graphs/weapons/spear.yml | 20 ++++++++ .../Crafting/Graphs/improvised/bat.yml | 4 ++ 47 files changed, 249 insertions(+), 97 deletions(-) diff --git a/Content.Server/Access/Systems/AccessOverriderSystem.cs b/Content.Server/Access/Systems/AccessOverriderSystem.cs index a0dbc96677b..4bb42a30a31 100644 --- a/Content.Server/Access/Systems/AccessOverriderSystem.cs +++ b/Content.Server/Access/Systems/AccessOverriderSystem.cs @@ -241,7 +241,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem var addedTags = newAccessList.Except(oldTags).Select(tag => "+" + tag).ToList(); var removedTags = oldTags.Except(newAccessList).Select(tag => "-" + tag).ToList(); - _adminLogger.Add(LogType.Action, LogImpact.Medium, + _adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(player):player} has modified {ToPrettyString(accessReaderEnt.Value):entity} with the following allowed access level holders: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]"); accessReaderEnt.Value.Comp.AccessLists = ConvertAccessListToHashSet(newAccessList); diff --git a/Content.Server/Access/Systems/IdCardConsoleSystem.cs b/Content.Server/Access/Systems/IdCardConsoleSystem.cs index a9e5d9a6d3e..c8fbe2ba9d9 100644 --- a/Content.Server/Access/Systems/IdCardConsoleSystem.cs +++ b/Content.Server/Access/Systems/IdCardConsoleSystem.cs @@ -168,7 +168,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem /*TODO: ECS SharedIdCardConsoleComponent 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, + _adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(player):player} has modified {ToPrettyString(targetId):entity} with the following accesses: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]"); } diff --git a/Content.Server/Access/Systems/IdCardSystem.cs b/Content.Server/Access/Systems/IdCardSystem.cs index a9b08aac8b3..9057fade722 100644 --- a/Content.Server/Access/Systems/IdCardSystem.cs +++ b/Content.Server/Access/Systems/IdCardSystem.cs @@ -88,7 +88,7 @@ public sealed class IdCardSystem : SharedIdCardSystem access.Tags.Add(random.ID); Dirty(uid, access); - _adminLogger.Add(LogType.Action, LogImpact.Medium, + _adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Microwave)} added {random.ID} access to {ToPrettyString(uid):entity}"); } diff --git a/Content.Server/Administration/Commands/ChangeCvarCommand.cs b/Content.Server/Administration/Commands/ChangeCvarCommand.cs index 984c9c1077a..66f93e4ebdb 100644 --- a/Content.Server/Administration/Commands/ChangeCvarCommand.cs +++ b/Content.Server/Administration/Commands/ChangeCvarCommand.cs @@ -180,7 +180,7 @@ public sealed class ChangeCvarCommand : IConsoleCommand var oldValue = _configurationManager.GetCVar(cvar); _configurationManager.SetCVar(cvar, parsed); _adminLogManager.Add(LogType.AdminCommands, - LogImpact.High, + LogImpact.Extreme, $"{shell.Player!.Name} ({shell.Player!.UserId}) changed CVAR {cvar} from {oldValue.ToString()} to {parsed.ToString()}" ); diff --git a/Content.Server/Administration/Logs/AdminLogManager.cs b/Content.Server/Administration/Logs/AdminLogManager.cs index e869d089dac..b345f55ad99 100644 --- a/Content.Server/Administration/Logs/AdminLogManager.cs +++ b/Content.Server/Administration/Logs/AdminLogManager.cs @@ -6,10 +6,14 @@ using Content.Server.Database; using Content.Server.GameTicking; using Content.Shared.Administration.Logs; using Content.Shared.CCVar; +using Content.Shared.Chat; using Content.Shared.Database; +using Content.Shared.Players.PlayTimeTracking; using Prometheus; using Robust.Shared; using Robust.Shared.Configuration; +using Robust.Shared.Network; +using Robust.Shared.Player; using Robust.Shared.Reflection; using Robust.Shared.Timing; @@ -25,6 +29,9 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa [Dependency] private readonly IDynamicTypeFactory _typeFactory = default!; [Dependency] private readonly IReflectionManager _reflection = default!; [Dependency] private readonly IDependencyCollection _dependencies = default!; + [Dependency] private readonly ISharedPlayerManager _player = default!; + [Dependency] private readonly ISharedPlaytimeManager _playtime = default!; + [Dependency] private readonly ISharedChatManager _chat = default!; public const string SawmillId = "admin.logs"; @@ -66,6 +73,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa private int _queueMax; private int _preRoundQueueMax; private int _dropThreshold; + private int _highImpactLogPlaytime; // Per update private TimeSpan _nextUpdateTime; @@ -100,6 +108,8 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa value => _preRoundQueueMax = value, true); _configuration.OnValueChanged(CCVars.AdminLogsDropThreshold, value => _dropThreshold = value, true); + _configuration.OnValueChanged(CCVars.AdminLogsHighLogPlaytime, + value => _highImpactLogPlaytime = value, true); if (_metricsEnabled) { @@ -309,6 +319,21 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa }; log.Players.Add(player); + if (impact == LogImpact.Extreme) // Always chat-notify Extreme logs + _chat.SendAdminAlert(message); + + if (impact == LogImpact.High) // Only chat-notify High logs if the player is below a threshold playtime + { + if (_highImpactLogPlaytime >= 0 && _player.TryGetSessionById(new NetUserId(id), out var session)) + { + var playtimes = _playtime.GetPlayTimes(session); + if (playtimes.TryGetValue(PlayTimeTrackingShared.TrackerOverall, out var overallTime) && + overallTime <= TimeSpan.FromHours(_highImpactLogPlaytime)) + { + _chat.SendAdminAlert(message); + } + } + } } if (preRound) diff --git a/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs b/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs index bc3b57bd5a3..7e84cbc7430 100644 --- a/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs +++ b/Content.Server/Ame/EntitySystems/AmeControllerSystem.cs @@ -240,7 +240,7 @@ public sealed class AmeControllerSystem : EntitySystem return; var humanReadableState = value ? "Inject" : "Not inject"; - _adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{EntityManager.ToPrettyString(user.Value):player} has set the AME to {humanReadableState}"); + _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{EntityManager.ToPrettyString(user.Value):player} has set the AME to {humanReadableState}"); } public void ToggleInjecting(EntityUid uid, EntityUid? user = null, AmeControllerComponent? controller = null) @@ -267,27 +267,15 @@ public sealed class AmeControllerSystem : EntitySystem return; var humanReadableState = controller.Injecting ? "Inject" : "Not inject"; - _adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{EntityManager.ToPrettyString(user.Value):player} has set the AME to inject {controller.InjectionAmount} while set to {humanReadableState}"); - /* This needs to be information which an admin is very likely to want to be informed about in order to be an admin alert or have a sound notification. - At the time of editing, players regularly "overclock" the AME and those cases require no admin attention. - // Admin alert var safeLimit = int.MaxValue; if (TryGetAMENodeGroup(uid, out var group)) safeLimit = group.CoreCount * 4; - if (oldValue <= safeLimit && value > safeLimit) - { - if (_gameTiming.CurTime > controller.EffectCooldown) - { - _chatManager.SendAdminAlert(user.Value, $"increased AME over safe limit to {controller.InjectionAmount}"); - _audioSystem.PlayGlobal("/Audio/Misc/adminlarm.ogg", - Filter.Empty().AddPlayers(_adminManager.ActiveAdmins), false, AudioParams.Default.WithVolume(-8f)); - controller.EffectCooldown = _gameTiming.CurTime + controller.CooldownDuration; - } - } - */ + var logImpact = (oldValue <= safeLimit && value > safeLimit) ? LogImpact.Extreme : LogImpact.Medium; + + _adminLogger.Add(LogType.Action, logImpact, $"{EntityManager.ToPrettyString(user.Value):player} has set the AME to inject {controller.InjectionAmount} while set to {humanReadableState}"); } public void AdjustInjectionAmount(EntityUid uid, int delta, EntityUid? user = null, AmeControllerComponent? controller = null) diff --git a/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs b/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs index 5380a1aa0a1..b647e026e30 100644 --- a/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs @@ -116,7 +116,7 @@ public sealed class InnerBodyAnomalySystem : SharedInnerBodyAnomalySystem _popup.PopupEntity(message, ent, ent, PopupType.MediumCaution); - _adminLog.Add(LogType.Anomaly,LogImpact.Extreme,$"{ToPrettyString(ent)} became anomaly host."); + _adminLog.Add(LogType.Anomaly,LogImpact.Medium,$"{ToPrettyString(ent)} became anomaly host."); } Dirty(ent); } diff --git a/Content.Server/Botany/SeedPrototype.cs b/Content.Server/Botany/SeedPrototype.cs index 7c5718b5698..22021f1fabc 100644 --- a/Content.Server/Botany/SeedPrototype.cs +++ b/Content.Server/Botany/SeedPrototype.cs @@ -1,6 +1,7 @@ using Content.Server.Botany.Components; using Content.Server.Botany.Systems; using Content.Shared.Atmos; +using Content.Shared.Database; using Content.Shared.EntityEffects; using Content.Shared.Random; using Robust.Shared.Audio; @@ -243,6 +244,18 @@ public partial class SeedData [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer))] public List MutationPrototypes = new(); + /// + /// Log impact for when the seed is planted. + /// + [DataField] + public LogImpact? PlantLogImpact = null; + + /// + /// Log impact for when the seed is harvested. + /// + [DataField] + public LogImpact? HarvestLogImpact = null; + public SeedData Clone() { DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed."); diff --git a/Content.Server/Botany/Systems/BotanySystem.Seed.cs b/Content.Server/Botany/Systems/BotanySystem.Seed.cs index 81645be34f4..e10414ebe5a 100644 --- a/Content.Server/Botany/Systems/BotanySystem.Seed.cs +++ b/Content.Server/Botany/Systems/BotanySystem.Seed.cs @@ -14,6 +14,8 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Content.Shared.Administration.Logs; +using Content.Shared.Database; namespace Content.Server.Botany.Systems; @@ -27,6 +29,7 @@ public sealed partial class BotanySystem : EntitySystem [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly RandomHelperSystem _randomHelper = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; public override void Initialize() { @@ -116,7 +119,12 @@ public sealed partial class BotanySystem : EntitySystem { if (position.IsValid(EntityManager) && proto.ProductPrototypes.Count > 0) + { + if (proto.HarvestLogImpact != null) + _adminLogger.Add(LogType.Botany, proto.HarvestLogImpact.Value, $"Auto-harvested {Loc.GetString(proto.Name):seed} at Pos:{position}."); + return GenerateProduct(proto, position, yieldMod); + } return Enumerable.Empty(); } @@ -131,6 +139,10 @@ public sealed partial class BotanySystem : EntitySystem var name = Loc.GetString(proto.DisplayName); _popupSystem.PopupCursor(Loc.GetString("botany-harvest-success-message", ("name", name)), user, PopupType.Medium); + + if (proto.HarvestLogImpact != null) + _adminLogger.Add(LogType.Botany, proto.HarvestLogImpact.Value, $"{ToPrettyString(user):player} harvested {Loc.GetString(proto.Name):seed} at Pos:{Transform(user).Coordinates}."); + return GenerateProduct(proto, Transform(user).Coordinates, yieldMod); } diff --git a/Content.Server/Botany/Systems/PlantHolderSystem.cs b/Content.Server/Botany/Systems/PlantHolderSystem.cs index 7eda4949a95..15cb82ef00c 100644 --- a/Content.Server/Botany/Systems/PlantHolderSystem.cs +++ b/Content.Server/Botany/Systems/PlantHolderSystem.cs @@ -23,7 +23,9 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; using Content.Server.Labels.Components; +using Content.Shared.Administration.Logs; using Content.Shared.Containers.ItemSlots; +using Content.Shared.Database; namespace Content.Server.Botany.Systems; @@ -42,6 +44,7 @@ public sealed class PlantHolderSystem : EntitySystem [Dependency] private readonly RandomHelperSystem _randomHelper = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; public const float HydroponicsSpeedMultiplier = 1f; @@ -188,6 +191,9 @@ public sealed class PlantHolderSystem : EntitySystem CheckLevelSanity(uid, component); UpdateSprite(uid, component); + if (seed.PlantLogImpact != null) + _adminLogger.Add(LogType.Botany, seed.PlantLogImpact.Value, $"{ToPrettyString(args.User):player} planted {Loc.GetString(seed.Name):seed} at Pos:{Transform(uid).Coordinates}."); + return; } diff --git a/Content.Server/Clothing/Systems/CursedMaskSystem.cs b/Content.Server/Clothing/Systems/CursedMaskSystem.cs index 86d4e801a8b..ef23df5f179 100644 --- a/Content.Server/Clothing/Systems/CursedMaskSystem.cs +++ b/Content.Server/Clothing/Systems/CursedMaskSystem.cs @@ -82,7 +82,7 @@ public sealed class CursedMaskSystem : SharedCursedMaskSystem { _mind.TransferTo(ent.Comp.StolenMind.Value, args.Wearer); _adminLog.Add(LogType.Action, - LogImpact.Extreme, + LogImpact.Medium, $"{ToPrettyString(args.Wearer):player} was restored to their body after the removal of {ToPrettyString(ent):entity}."); ent.Comp.StolenMind = null; } diff --git a/Content.Server/Communications/CommunicationsConsoleSystem.cs b/Content.Server/Communications/CommunicationsConsoleSystem.cs index abcd93f3280..b4303ee50ad 100644 --- a/Content.Server/Communications/CommunicationsConsoleSystem.cs +++ b/Content.Server/Communications/CommunicationsConsoleSystem.cs @@ -312,7 +312,7 @@ namespace Content.Server.Communications } _roundEndSystem.RequestRoundEnd(uid); - _adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(mob):player} has called the shuttle."); + _adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(mob):player} has called the shuttle."); } private void OnRecallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleRecallEmergencyShuttleMessage message) @@ -327,7 +327,7 @@ namespace Content.Server.Communications } _roundEndSystem.CancelRoundEndCountdown(uid); - _adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(message.Actor):player} has recalled the shuttle."); + _adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(message.Actor):player} has recalled the shuttle."); } } diff --git a/Content.Server/Construction/Completions/AdminLog.cs b/Content.Server/Construction/Completions/AdminLog.cs index 82758634d9c..bc5b45e4a80 100644 --- a/Content.Server/Construction/Completions/AdminLog.cs +++ b/Content.Server/Construction/Completions/AdminLog.cs @@ -25,7 +25,7 @@ public sealed partial class AdminLog : IGraphAction var logManager = IoCManager.Resolve(); if (userUid.HasValue) - logManager.Add(LogType, Impact, $"{Message} - Entity: {entityManager.ToPrettyString(uid):entity}, User: {entityManager.ToPrettyString(userUid.Value):user}"); + logManager.Add(LogType, Impact, $"{Message} - Entity: {entityManager.ToPrettyString(uid):entity}, User: {entityManager.ToPrettyString(userUid.Value):player}"); else logManager.Add(LogType, Impact, $"{Message} - Entity: {entityManager.ToPrettyString(uid):entity}"); } diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index 718475754f2..02d3ebd0a15 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -225,12 +225,12 @@ namespace Content.Server.Decals if (eventArgs.SenderSession.AttachedEntity != null) { - _adminLogger.Add(LogType.CrayonDraw, LogImpact.High, + _adminLogger.Add(LogType.CrayonDraw, LogImpact.Low, $"{ToPrettyString(eventArgs.SenderSession.AttachedEntity.Value):actor} drew a {ev.Decal.Color} {ev.Decal.Id} at {ev.Coordinates}"); } else { - _adminLogger.Add(LogType.CrayonDraw, LogImpact.High, + _adminLogger.Add(LogType.CrayonDraw, LogImpact.Low, $"{eventArgs.SenderSession.Name} drew a {ev.Decal.Color} {ev.Decal.Id} at {ev.Coordinates}"); } } @@ -259,12 +259,12 @@ namespace Content.Server.Decals { if (eventArgs.SenderSession.AttachedEntity != null) { - _adminLogger.Add(LogType.CrayonDraw, LogImpact.High, + _adminLogger.Add(LogType.CrayonDraw, LogImpact.Low, $"{ToPrettyString(eventArgs.SenderSession.AttachedEntity.Value):actor} removed a {decal.Color} {decal.Id} at {ev.Coordinates}"); } else { - _adminLogger.Add(LogType.CrayonDraw, LogImpact.High, + _adminLogger.Add(LogType.CrayonDraw, LogImpact.Low, $"{eventArgs.SenderSession.Name} removed a {decal.Color} {decal.Id} at {ev.Coordinates}"); } diff --git a/Content.Server/Destructible/DestructibleSystem.cs b/Content.Server/Destructible/DestructibleSystem.cs index f156d517a3a..48b38e9d019 100644 --- a/Content.Server/Destructible/DestructibleSystem.cs +++ b/Content.Server/Destructible/DestructibleSystem.cs @@ -21,6 +21,8 @@ using Robust.Shared.Containers; using Robust.Shared.Prototypes; using Robust.Shared.Random; using System.Linq; +using Content.Shared.Humanoid; +using Robust.Shared.Player; namespace Content.Server.Destructible { @@ -61,9 +63,12 @@ namespace Content.Server.Destructible { RaiseLocalEvent(uid, new DamageThresholdReached(component, threshold), true); + var logImpact = LogImpact.Low; // Convert behaviors into string for logs var triggeredBehaviors = string.Join(", ", threshold.Behaviors.Select(b => { + if (logImpact <= b.Impact) + logImpact = b.Impact; if (b is DoActsBehavior doActsBehavior) { return $"{b.GetType().Name}:{doActsBehavior.Acts.ToString()}"; @@ -71,14 +76,20 @@ namespace Content.Server.Destructible return b.GetType().Name; })); + // If it doesn't have a humanoid component, it's probably not particularly notable? + if (logImpact > LogImpact.Medium && !HasComp(uid)) + logImpact = LogImpact.Medium; + if (args.Origin != null) { - _adminLogger.Add(LogType.Damaged, LogImpact.Medium, + _adminLogger.Add(LogType.Damaged, + logImpact, $"{ToPrettyString(args.Origin.Value):actor} caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]"); } else { - _adminLogger.Add(LogType.Damaged, LogImpact.Medium, + _adminLogger.Add(LogType.Damaged, + logImpact, $"Unknown damage source caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]"); } diff --git a/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs index c83fed19069..9aa798a3d09 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/GibBehavior.cs @@ -1,4 +1,5 @@ using Content.Shared.Body.Components; +using Content.Shared.Database; using JetBrains.Annotations; namespace Content.Server.Destructible.Thresholds.Behaviors @@ -9,6 +10,8 @@ namespace Content.Server.Destructible.Thresholds.Behaviors { [DataField("recursive")] private bool _recursive = true; + public LogImpact Impact => LogImpact.Extreme; + public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null) { if (system.EntityManager.TryGetComponent(owner, out BodyComponent? body)) diff --git a/Content.Server/Destructible/Thresholds/Behaviors/IThresholdBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/IThresholdBehavior.cs index b5e78fd80c5..0cf0cc032cd 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/IThresholdBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/IThresholdBehavior.cs @@ -1,7 +1,11 @@ -namespace Content.Server.Destructible.Thresholds.Behaviors +using Content.Shared.Database; + +namespace Content.Server.Destructible.Thresholds.Behaviors { public interface IThresholdBehavior { + public LogImpact Impact => LogImpact.Low; + /// /// Executes this behavior. /// diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index 57759fedfe9..6bf237f46fa 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -256,11 +256,12 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem } else { - _adminLogger.Add(LogType.Explosion, LogImpact.High, - $"{ToPrettyString(user.Value):user} caused {ToPrettyString(uid):entity} to explode ({typeId}) at Pos:{(posFound ? $"{gridPos:coordinates}" : "[Grid or Map not found]")} with intensity {totalIntensity} slope {slope}"); var alertMinExplosionIntensity = _cfg.GetCVar(CCVars.AdminAlertExplosionMinIntensity); - if (alertMinExplosionIntensity > -1 && totalIntensity >= alertMinExplosionIntensity) - _chat.SendAdminAlert(user.Value, $"caused {ToPrettyString(uid)} to explode ({typeId}:{totalIntensity}) at Pos:{(posFound ? $"{gridPos:coordinates}" : "[Grid or Map not found]")}"); + var logImpact = (alertMinExplosionIntensity > -1 && totalIntensity >= alertMinExplosionIntensity) + ? LogImpact.Extreme + : LogImpact.High; + _adminLogger.Add(LogType.Explosion, logImpact, + $"{ToPrettyString(user.Value):user} caused {ToPrettyString(uid):entity} to explode ({typeId}) at Pos:{(posFound ? $"{gridPos:coordinates}" : "[Grid or Map not found]")} with intensity {totalIntensity} slope {slope}"); } } diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.Voice.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.Voice.cs index 8dd170e6676..9d11a9dad77 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.Voice.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.Voice.cs @@ -50,7 +50,7 @@ namespace Content.Server.Explosion.EntitySystems if (!string.IsNullOrWhiteSpace(component.KeyPhrase) && message.Contains(component.KeyPhrase, StringComparison.InvariantCultureIgnoreCase)) { - _adminLogger.Add(LogType.Trigger, LogImpact.High, + _adminLogger.Add(LogType.Trigger, LogImpact.Medium, $"A voice-trigger on {ToPrettyString(ent):entity} was triggered by {ToPrettyString(args.Source):speaker} speaking the key-phrase {component.KeyPhrase}."); Trigger(ent, args.Source); diff --git a/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs b/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs index 9b70426faa7..6f28331ade4 100644 --- a/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/KitchenSpikeSystem.cs @@ -7,6 +7,7 @@ using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.DoAfter; using Content.Shared.DragDrop; +using Content.Shared.Humanoid; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; @@ -143,7 +144,11 @@ namespace Content.Server.Kitchen.EntitySystems if (!Resolve(uid, ref component) || !Resolve(victimUid, ref butcherable)) return; - _logger.Add(LogType.Gib, LogImpact.Extreme, $"{ToPrettyString(userUid):user} kitchen spiked {ToPrettyString(victimUid):target}"); + var logImpact = LogImpact.Medium; + if (HasComp(victimUid)) + logImpact = LogImpact.Extreme; + + _logger.Add(LogType.Gib, logImpact, $"{ToPrettyString(userUid):user} kitchen spiked {ToPrettyString(victimUid):target}"); // TODO VERY SUS component.PrototypesToSpawn = EntitySpawnCollection.GetSpawns(butcherable.SpawnedEntities, _random); diff --git a/Content.Server/Materials/MaterialReclaimerSystem.cs b/Content.Server/Materials/MaterialReclaimerSystem.cs index d179284595d..60b1a99e31d 100644 --- a/Content.Server/Materials/MaterialReclaimerSystem.cs +++ b/Content.Server/Materials/MaterialReclaimerSystem.cs @@ -24,6 +24,7 @@ using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Utility; using System.Linq; +using Content.Shared.Humanoid; namespace Content.Server.Materials; @@ -186,7 +187,8 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem if (CanGib(uid, item, component)) { - _adminLogger.Add(LogType.Gib, LogImpact.Extreme, $"{ToPrettyString(item):victim} was gibbed by {ToPrettyString(uid):entity} "); + var logImpact = HasComp(item) ? LogImpact.Extreme : LogImpact.Medium; + _adminLogger.Add(LogType.Gib, logImpact, $"{ToPrettyString(item):victim} was gibbed by {ToPrettyString(uid):entity} "); SpawnChemicalsFromComposition(uid, item, completion, false, component, xform); _body.GibBody(item, true); _appearance.SetData(uid, RecyclerVisuals.Bloody, true); diff --git a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs index 868e6d99f25..f6b751c398a 100644 --- a/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs +++ b/Content.Server/Medical/BiomassReclaimer/BiomassReclaimerSystem.cs @@ -182,7 +182,7 @@ namespace Content.Server.Medical.BiomassReclaimer _throwing.TryThrow(args.Climber, direction, 0.5f); return; } - _adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(args.Instigator):player} used a biomass reclaimer to gib {ToPrettyString(args.Climber):target} in {ToPrettyString(reclaimer):reclaimer}"); + _adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Instigator):player} used a biomass reclaimer to gib {ToPrettyString(args.Climber):target} in {ToPrettyString(reclaimer):reclaimer}"); StartProcessing(args.Climber, reclaimer); } @@ -195,7 +195,7 @@ namespace Content.Server.Medical.BiomassReclaimer if (args.Args.Used == null || args.Args.Target == null || !HasComp(args.Args.Target.Value)) return; - _adminLogger.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(args.Args.User):player} used a biomass reclaimer to gib {ToPrettyString(args.Args.Target.Value):target} in {ToPrettyString(reclaimer):reclaimer}"); + _adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.Args.User):player} used a biomass reclaimer to gib {ToPrettyString(args.Args.Target.Value):target} in {ToPrettyString(reclaimer):reclaimer}"); StartProcessing(args.Args.Used.Value, reclaimer); args.Handled = true; diff --git a/Content.Server/Mining/MeteorSystem.cs b/Content.Server/Mining/MeteorSystem.cs index fc00147f70f..3b0c6920b3b 100644 --- a/Content.Server/Mining/MeteorSystem.cs +++ b/Content.Server/Mining/MeteorSystem.cs @@ -35,7 +35,7 @@ public sealed class MeteorSystem : EntitySystem { threshold = mobThreshold.Value; if (HasComp(args.OtherEntity)) - _adminLog.Add(LogType.Action, LogImpact.Extreme, $"{ToPrettyString(args.OtherEntity):player} was struck by meteor {ToPrettyString(uid):ent} and killed instantly."); + _adminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(args.OtherEntity):player} was struck by meteor {ToPrettyString(uid):ent} and killed instantly."); } else if (_destructible.TryGetDestroyedAt(args.OtherEntity, out var destroyThreshold)) { diff --git a/Content.Server/Morgue/CrematoriumSystem.cs b/Content.Server/Morgue/CrematoriumSystem.cs index 656457dc985..52f5ca312d1 100644 --- a/Content.Server/Morgue/CrematoriumSystem.cs +++ b/Content.Server/Morgue/CrematoriumSystem.cs @@ -87,7 +87,7 @@ public sealed class CrematoriumSystem : EntitySystem Text = Loc.GetString("cremate-verb-get-data-text"), // TODO VERB ICON add flame/burn symbol? Act = () => TryCremate(uid, component, storage), - Impact = LogImpact.Medium // could be a body? or evidence? I dunno. + Impact = LogImpact.High // could be a body? or evidence? I dunno. }; args.Verbs.Add(verb); } diff --git a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs b/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs index 44e90537b5d..f11a2c9041a 100644 --- a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs @@ -195,7 +195,7 @@ public sealed class DrinkSystem : SharedDrinkSystem _popup.PopupEntity(Loc.GetString("drink-component-force-feed", ("user", userName)), user, target); // logging - _adminLogger.Add(LogType.ForceFeed, LogImpact.Medium, $"{ToPrettyString(user):user} is forcing {ToPrettyString(target):target} to drink {ToPrettyString(item):drink} {SharedSolutionContainerSystem.ToPrettyString(drinkSolution)}"); + _adminLogger.Add(LogType.ForceFeed, LogImpact.High, $"{ToPrettyString(user):user} is forcing {ToPrettyString(target):target} to drink {ToPrettyString(item):drink} {SharedSolutionContainerSystem.ToPrettyString(drinkSolution)}"); } else { diff --git a/Content.Server/Placement/PlacementLoggerSystem.cs b/Content.Server/Placement/PlacementLoggerSystem.cs index d590754423d..55fc3b7f6fd 100644 --- a/Content.Server/Placement/PlacementLoggerSystem.cs +++ b/Content.Server/Placement/PlacementLoggerSystem.cs @@ -32,13 +32,13 @@ public sealed class PlacementLoggerSystem : EntitySystem }; if (actorEntity != null) - _adminLogger.Add(logType, LogImpact.High, + _adminLogger.Add(logType, LogImpact.Medium, $"{ToPrettyString(actorEntity.Value):actor} used placement system to {ev.PlacementEventAction.ToString().ToLower()} {ToPrettyString(ev.EditedEntity):subject} at {ev.Coordinates}"); else if (actor != null) - _adminLogger.Add(logType, LogImpact.High, + _adminLogger.Add(logType, LogImpact.Medium, $"{actor:actor} used placement system to {ev.PlacementEventAction.ToString().ToLower()} {ToPrettyString(ev.EditedEntity):subject} at {ev.Coordinates}"); else - _adminLogger.Add(logType, LogImpact.High, + _adminLogger.Add(logType, LogImpact.Medium, $"Placement system {ev.PlacementEventAction.ToString().ToLower()}ed {ToPrettyString(ev.EditedEntity):subject} at {ev.Coordinates}"); } @@ -48,13 +48,13 @@ public sealed class PlacementLoggerSystem : EntitySystem var actorEntity = actor?.AttachedEntity; if (actorEntity != null) - _adminLogger.Add(LogType.Tile, LogImpact.High, + _adminLogger.Add(LogType.Tile, LogImpact.Medium, $"{ToPrettyString(actorEntity.Value):actor} used placement system to set tile {_tileDefinitionManager[ev.TileType].Name} at {ev.Coordinates}"); else if (actor != null) - _adminLogger.Add(LogType.Tile, LogImpact.High, + _adminLogger.Add(LogType.Tile, LogImpact.Medium, $"{actor} used placement system to set tile {_tileDefinitionManager[ev.TileType].Name} at {ev.Coordinates}"); else - _adminLogger.Add(LogType.Tile, LogImpact.High, + _adminLogger.Add(LogType.Tile, LogImpact.Medium, $"Placement system set tile {_tileDefinitionManager[ev.TileType].Name} at {ev.Coordinates}"); } } diff --git a/Content.Server/Power/EntitySystems/CableSystem.cs b/Content.Server/Power/EntitySystems/CableSystem.cs index db44323007a..8fc7edacf35 100644 --- a/Content.Server/Power/EntitySystems/CableSystem.cs +++ b/Content.Server/Power/EntitySystems/CableSystem.cs @@ -53,7 +53,7 @@ public sealed partial class CableSystem : EntitySystem if (_electrocutionSystem.TryDoElectrifiedAct(uid, args.User)) return; - _adminLogger.Add(LogType.CableCut, LogImpact.Medium, $"The {ToPrettyString(uid)} at {xform.Coordinates} was cut by {ToPrettyString(args.User)}."); + _adminLogger.Add(LogType.CableCut, LogImpact.High, $"The {ToPrettyString(uid)} at {xform.Coordinates} was cut by {ToPrettyString(args.User)}."); Spawn(cable.CableDroppedOnCutPrototype, xform.Coordinates); QueueDel(uid); diff --git a/Content.Server/Projectiles/ProjectileSystem.cs b/Content.Server/Projectiles/ProjectileSystem.cs index f1df25d58c7..64bb678321b 100644 --- a/Content.Server/Projectiles/ProjectileSystem.cs +++ b/Content.Server/Projectiles/ProjectileSystem.cs @@ -65,7 +65,7 @@ public sealed class ProjectileSystem : SharedProjectileSystem } _adminLogger.Add(LogType.BulletHit, - HasComp(target) ? LogImpact.Extreme : LogImpact.High, + LogImpact.Medium, $"Projectile {ToPrettyString(uid):projectile} shot by {ToPrettyString(component.Shooter!.Value):user} hit {otherName:target} and dealt {modifiedDamage.GetTotal():damage} damage"); } diff --git a/Content.Server/Respawn/SpecialRespawnSystem.cs b/Content.Server/Respawn/SpecialRespawnSystem.cs index a403818e742..e7a2385e74d 100644 --- a/Content.Server/Respawn/SpecialRespawnSystem.cs +++ b/Content.Server/Respawn/SpecialRespawnSystem.cs @@ -136,7 +136,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem private void Respawn(EntityUid oldEntity, string prototype, EntityCoordinates coords) { var entity = Spawn(prototype, coords); - _adminLog.Add(LogType.Respawn, LogImpact.High, $"{ToPrettyString(oldEntity)} was deleted and was respawned at {coords.ToMap(EntityManager, _transform)} as {ToPrettyString(entity)}"); + _adminLog.Add(LogType.Respawn, LogImpact.Extreme, $"{ToPrettyString(oldEntity)} was deleted and was respawned at {coords.ToMap(EntityManager, _transform)} as {ToPrettyString(entity)}"); _chat.SendAdminAlert($"{MetaData(oldEntity).EntityName} was deleted and was respawned as {ToPrettyString(entity)}"); } diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs index ede0b687fcc..09aad1d931a 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs @@ -372,7 +372,7 @@ public sealed partial class EmergencyShuttleSystem { if (EarlyLaunchAuthorized || !EmergencyShuttleArrived || _consoleAccumulator <= _authorizeTime) return false; - _logger.Add(LogType.EmergencyShuttle, LogImpact.Extreme, $"Emergency shuttle launch authorized"); + _logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle launch authorized"); _consoleAccumulator = _authorizeTime; EarlyLaunchAuthorized = true; RaiseLocalEvent(new EmergencyShuttleAuthorizedEvent()); diff --git a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs index 2a2952916ec..729328b8bd7 100644 --- a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs +++ b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs @@ -130,7 +130,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem || _tagSystem.HasTag(morsel, "HighRiskItem") || HasComp(morsel)) { - _adminLogger.Add(LogType.EntityDelete, LogImpact.Extreme, $"{ToPrettyString(morsel)} entered the event horizon of {ToPrettyString(hungry)} and was deleted"); + _adminLogger.Add(LogType.EntityDelete, LogImpact.High, $"{ToPrettyString(morsel):player} entered the event horizon of {ToPrettyString(hungry)} and was deleted"); } EntityManager.QueueDeleteEntity(morsel); diff --git a/Content.Server/Teleportation/HandTeleporterSystem.cs b/Content.Server/Teleportation/HandTeleporterSystem.cs index 78e881d76a0..5c9baf18546 100644 --- a/Content.Server/Teleportation/HandTeleporterSystem.cs +++ b/Content.Server/Teleportation/HandTeleporterSystem.cs @@ -95,7 +95,7 @@ public sealed class HandTeleporterSystem : EntitySystem var timeout = EnsureComp(user); timeout.EnteredPortal = null; component.FirstPortal = Spawn(component.FirstPortalPrototype, Transform(user).Coordinates); - _adminLogger.Add(LogType.EntitySpawn, LogImpact.Low, $"{ToPrettyString(user):player} opened {ToPrettyString(component.FirstPortal.Value)} at {Transform(component.FirstPortal.Value).Coordinates} using {ToPrettyString(uid)}"); + _adminLogger.Add(LogType.EntitySpawn, LogImpact.High, $"{ToPrettyString(user):player} opened {ToPrettyString(component.FirstPortal.Value)} at {Transform(component.FirstPortal.Value).Coordinates} using {ToPrettyString(uid)}"); _audio.PlayPvs(component.NewPortalSound, uid); } else if (Deleted(component.SecondPortal)) @@ -113,7 +113,7 @@ public sealed class HandTeleporterSystem : EntitySystem var timeout = EnsureComp(user); timeout.EnteredPortal = null; component.SecondPortal = Spawn(component.SecondPortalPrototype, Transform(user).Coordinates); - _adminLogger.Add(LogType.EntitySpawn, LogImpact.Low, $"{ToPrettyString(user):player} opened {ToPrettyString(component.SecondPortal.Value)} at {Transform(component.SecondPortal.Value).Coordinates} linked to {ToPrettyString(component.FirstPortal!.Value)} using {ToPrettyString(uid)}"); + _adminLogger.Add(LogType.EntitySpawn, LogImpact.High, $"{ToPrettyString(user):player} opened {ToPrettyString(component.SecondPortal.Value)} at {Transform(component.SecondPortal.Value).Coordinates} linked to {ToPrettyString(component.FirstPortal!.Value)} using {ToPrettyString(uid)}"); _link.TryLink(component.FirstPortal!.Value, component.SecondPortal.Value, true); _audio.PlayPvs(component.NewPortalSound, uid); } @@ -132,7 +132,7 @@ public sealed class HandTeleporterSystem : EntitySystem portalStrings += " and "; portalStrings += ToPrettyString(component.SecondPortal); if (portalStrings != "") - _adminLogger.Add(LogType.EntityDelete, LogImpact.Low, $"{ToPrettyString(user):player} closed {portalStrings} with {ToPrettyString(uid)}"); + _adminLogger.Add(LogType.EntityDelete, LogImpact.High, $"{ToPrettyString(user):player} closed {portalStrings} with {ToPrettyString(uid)}"); // Clear both portals if (!Deleted(component.FirstPortal)) diff --git a/Content.Shared.Database/LogImpact.cs b/Content.Shared.Database/LogImpact.cs index eafcf4dc27c..9f0d6a86f5a 100644 --- a/Content.Shared.Database/LogImpact.cs +++ b/Content.Shared.Database/LogImpact.cs @@ -4,8 +4,8 @@ [Serializable] public enum LogImpact : sbyte { - Low = -1, - Medium = 0, - High = 1, - Extreme = 2 // Nar'Sie just dropped + Low = -1, // General logging + Medium = 0, // Has impact on the round but not necessary for admins to be notified of + High = 1, // Notable logs that come up in normal gameplay; new players causing these will pop up as admin alerts! + Extreme = 2 // Irreversible round-impacting logs admins should always be notified of, OR big admin actions!! } diff --git a/Content.Shared.Database/LogType.cs b/Content.Shared.Database/LogType.cs index a868d0e3842..321a89d591f 100644 --- a/Content.Shared.Database/LogType.cs +++ b/Content.Shared.Database/LogType.cs @@ -459,4 +459,9 @@ public enum LogType /// A player was selected or assigned antag status /// AntagSelection = 99, + + /// + /// Logs related to botany, such as planting and harvesting crops + /// + Botany = 100, } diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index 0d7c926f763..f2afbe2f518 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -123,7 +123,7 @@ public abstract class SharedAnomalySystem : EntitySystem if (HasComp(uid)) return; - AdminLog.Add(LogType.Anomaly, LogImpact.Extreme, $"Anomaly {ToPrettyString(uid)} began to go supercritical."); + AdminLog.Add(LogType.Anomaly, LogImpact.High, $"Anomaly {ToPrettyString(uid)} began to go supercritical."); if (_net.IsServer) Log.Info($"Anomaly is going supercritical. Entity: {ToPrettyString(uid)}"); diff --git a/Content.Shared/CCVar/CCVars.Admin.Logs.cs b/Content.Shared/CCVar/CCVars.Admin.Logs.cs index 862456ddfdd..f760f3418f3 100644 --- a/Content.Shared/CCVar/CCVars.Admin.Logs.cs +++ b/Content.Shared/CCVar/CCVars.Admin.Logs.cs @@ -39,4 +39,11 @@ public sealed partial class CCVars public static readonly CVarDef AdminLogsServerName = CVarDef.Create("adminlogs.server_name", "unknown", CVar.SERVERONLY); + + /// + /// Any session below this playtime will send an admin alert whenever they cause a LogImpact.High log. + /// Set to -1 to disable. + /// + public static readonly CVarDef AdminLogsHighLogPlaytime = + CVarDef.Create("adminlogs.high_log_playtime", 5, CVar.SERVERONLY); } diff --git a/Content.Shared/Cuffs/SharedCuffableSystem.cs b/Content.Shared/Cuffs/SharedCuffableSystem.cs index 815760626d9..a1f5ec2a1c0 100644 --- a/Content.Shared/Cuffs/SharedCuffableSystem.cs +++ b/Content.Shared/Cuffs/SharedCuffableSystem.cs @@ -361,7 +361,7 @@ namespace Content.Shared.Cuffs ("otherName", Identity.Name(target, EntityManager, user))), user, user); _popup.PopupClient(Loc.GetString("handcuff-component-cuff-by-other-success-message", ("otherName", Identity.Name(user, EntityManager, target))), target, target); - _adminLog.Add(LogType.Action, LogImpact.Medium, + _adminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(user):player} has cuffed {ToPrettyString(target):player}"); } } @@ -647,7 +647,7 @@ namespace Content.Shared.Cuffs if (!_doAfter.TryStartDoAfter(doAfterEventArgs)) return; - _adminLog.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user)} is trying to uncuff {ToPrettyString(target)}"); + _adminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(user):player} is trying to uncuff {ToPrettyString(target):subject}"); var popupText = user == target ? "cuffable-component-start-uncuffing-self-observer" @@ -726,12 +726,12 @@ namespace Content.Shared.Cuffs { _popup.PopupEntity(Loc.GetString("cuffable-component-remove-cuffs-by-other-success-message", ("otherName", Identity.Name(user.Value, EntityManager, user))), target, target); - _adminLog.Add(LogType.Action, LogImpact.Medium, + _adminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(user):player} has successfully uncuffed {ToPrettyString(target):player}"); } else { - _adminLog.Add(LogType.Action, LogImpact.Medium, + _adminLog.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(user):player} has successfully uncuffed themselves"); } } diff --git a/Content.Shared/Mobs/Systems/MobStateSystem.StateMachine.cs b/Content.Shared/Mobs/Systems/MobStateSystem.StateMachine.cs index 5928b3871ff..b389d672757 100644 --- a/Content.Shared/Mobs/Systems/MobStateSystem.StateMachine.cs +++ b/Content.Shared/Mobs/Systems/MobStateSystem.StateMachine.cs @@ -1,5 +1,7 @@ using Content.Shared.Database; +using Content.Shared.Humanoid; using Content.Shared.Mobs.Components; +using Robust.Shared.Player; namespace Content.Shared.Mobs.Systems; @@ -110,8 +112,10 @@ public partial class MobStateSystem var ev = new MobStateChangedEvent(target, component, oldState, newState, origin); OnStateChanged(target, component, oldState, newState); RaiseLocalEvent(target, ev, true); - _adminLogger.Add(LogType.Damaged, oldState == MobState.Alive ? LogImpact.Low : LogImpact.Medium, - $"{ToPrettyString(target):user} state changed from {oldState} to {newState}"); + if (origin != null && HasComp(origin) && HasComp(target) && oldState < newState) + _adminLogger.Add(LogType.Damaged, LogImpact.High, $"{ToPrettyString(origin):player} caused {ToPrettyString(target):player} state to change from {oldState} to {newState}"); + else + _adminLogger.Add(LogType.Damaged, oldState == MobState.Alive ? LogImpact.Low : LogImpact.Medium, $"{ToPrettyString(target):user} state changed from {oldState} to {newState}"); Dirty(target, component); } diff --git a/Content.Shared/Roles/SharedRoleSystem.cs b/Content.Shared/Roles/SharedRoleSystem.cs index d624bc512eb..583c81d680e 100644 --- a/Content.Shared/Roles/SharedRoleSystem.cs +++ b/Content.Shared/Roles/SharedRoleSystem.cs @@ -251,14 +251,14 @@ public abstract class SharedRoleSystem : EntitySystem else { var error = $"The Character Window of {_minds.MindOwnerLoggingString(comp)} potentially did not update immediately : session error"; - _adminLogger.Add(LogType.Mind, LogImpact.High, $"{error}"); + _adminLogger.Add(LogType.Mind, LogImpact.Medium, $"{error}"); } if (comp.OwnedEntity is null) { Log.Error($"{ToPrettyString(mind)} does not have an OwnedEntity!"); _adminLogger.Add(LogType.Mind, - LogImpact.High, + LogImpact.Medium, $"Role Type of {ToPrettyString(mind)} changed to {roleTypeId}"); return; } diff --git a/Content.Shared/Strip/SharedStrippableSystem.cs b/Content.Shared/Strip/SharedStrippableSystem.cs index ee40599493f..3645b5a0b93 100644 --- a/Content.Shared/Strip/SharedStrippableSystem.cs +++ b/Content.Shared/Strip/SharedStrippableSystem.cs @@ -339,7 +339,7 @@ public abstract class SharedStrippableSystem : EntitySystem RaiseLocalEvent(item, new DroppedEvent(user), true); // Gas tank internals etc. _handsSystem.PickupOrDrop(user, item, animateUser: stealth, animate: !stealth); - _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):actor} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s {slot} slot"); + _adminLogger.Add(LogType.Stripping, LogImpact.High, $"{ToPrettyString(user):actor} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s {slot} slot"); } /// @@ -544,7 +544,7 @@ public abstract class SharedStrippableSystem : EntitySystem _handsSystem.TryDrop(target, item, checkActionBlocker: false, handsComp: target.Comp); _handsSystem.PickupOrDrop(user, item, animateUser: stealth, animate: !stealth, handsComp: user.Comp); - _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):actor} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s hands"); + _adminLogger.Add(LogType.Stripping, LogImpact.High, $"{ToPrettyString(user):actor} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s hands"); // Hand update will trigger strippable update. } diff --git a/Resources/Locale/en-US/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/chat/managers/chat-manager.ftl index c3d35c97395..704d96cc15f 100644 --- a/Resources/Locale/en-US/chat/managers/chat-manager.ftl +++ b/Resources/Locale/en-US/chat/managers/chat-manager.ftl @@ -49,7 +49,7 @@ chat-manager-dead-channel-name = DEAD chat-manager-admin-channel-name = ADMIN chat-manager-rate-limited = You are sending messages too quickly! -chat-manager-rate-limit-admin-announcement = Player { $player } breached chat rate limits. Watch them if this is a regular occurence. +chat-manager-rate-limit-admin-announcement = Rate limit warning: { $player } ## Speech verbs for chat diff --git a/Resources/Prototypes/Hydroponics/seeds.yml b/Resources/Prototypes/Hydroponics/seeds.yml index de7be63d2b8..0df10088346 100644 --- a/Resources/Prototypes/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Hydroponics/seeds.yml @@ -622,6 +622,8 @@ noun: seeds-noun-seeds displayName: seeds-killertomato-display-name plantRsi: Objects/Specific/Hydroponics/tomatokiller.rsi + plantLogImpact: High + harvestLogImpact: High packetPrototype: KillerTomatoSeeds productPrototypes: - MobTomatoKiller @@ -1063,6 +1065,8 @@ displayName: seeds-deathnettle-display-name plantRsi: Objects/Specific/Hydroponics/death_nettle.rsi packetPrototype: DeathNettleSeeds + plantLogImpact: High + harvestLogImpact: High productPrototypes: - DeathNettle lifespan: 25 diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/furniture/meatspike.yml b/Resources/Prototypes/Recipes/Construction/Graphs/furniture/meatspike.yml index 02e141826cb..f97322a9fab 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/furniture/meatspike.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/furniture/meatspike.yml @@ -2,26 +2,29 @@ id: MeatSpike start: start graph: - - node: start - actions: - - !type:DeleteEntity {} - edges: - - to: MeatSpike - completed: - - !type:SnapToGrid - southRotation: true - steps: - - material: Steel - amount: 15 - doAfter: 2 - - node: MeatSpike - entity: KitchenSpike - edges: - - to: start - completed: - - !type:SpawnPrototype - prototype: SheetSteel1 - amount: 15 - steps: - - tool: Screwing - doAfter: 1 + - node: start + actions: + - !type:DeleteEntity {} + edges: + - to: MeatSpike + completed: + - !type:AdminLog # Needs a log for start of attempt in addition to the completion log + message: "Construction" + impact: High + - !type:SnapToGrid + southRotation: true + steps: + - material: Steel + amount: 15 + doAfter: 2 + - node: MeatSpike + entity: KitchenSpike + edges: + - to: start + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 15 + steps: + - tool: Screwing + doAfter: 1 diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/grille.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/grille.yml index 33aa50e1c16..02e32b18b86 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/grille.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/grille.yml @@ -6,6 +6,9 @@ edges: - to: grille completed: + - !type:AdminLog # Needs a log for start of attempt in addition to the completion log + message: "Construction" + impact: High - !type:SnapToGrid southRotation: true steps: diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/weapons/shiv.yml b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/shiv.yml index 51a1f9905e0..a434e707293 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/weapons/shiv.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/shiv.yml @@ -6,6 +6,10 @@ entity: ShardGlass edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - material: Cloth amount: 1 @@ -20,6 +24,10 @@ - node: start edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - tag: GlassShard name: glass shard @@ -41,6 +49,10 @@ entity: ShardGlassReinforced edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - material: Cloth amount: 1 @@ -55,6 +67,10 @@ - node: start edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - tag: ReinforcedGlassShard name: reinforced glass shard @@ -76,6 +92,10 @@ entity: ShardGlassPlasma edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - material: Cloth amount: 1 @@ -90,6 +110,10 @@ - node: start edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - tag: PlasmaGlassShard name: plasma glass shard @@ -111,6 +135,10 @@ entity: ShardGlassUranium edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - material: Cloth amount: 1 @@ -125,6 +153,10 @@ - node: start edges: - to: icon + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - tag: UraniumGlassShard name: uranium glass shard diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/weapons/spear.yml b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/spear.yml index 3d65c13fe26..d80df72dba9 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/weapons/spear.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/spear.yml @@ -5,6 +5,10 @@ - node: start edges: - to: spear + completed: + - !type:AdminLog # Needs a log for start of attempt in addition to the completion log + message: "Construction" + impact: High steps: - material: MetalRod amount: 2 @@ -28,6 +32,10 @@ - node: start edges: - to: spear + completed: + - !type:AdminLog # Needs a log for start of attempt in addition to the completion log + message: "Construction" + impact: High steps: - material: MetalRod amount: 2 @@ -51,6 +59,10 @@ - node: start edges: - to: spear + completed: + - !type:AdminLog # Needs a log for start of attempt in addition to the completion log + message: "Construction" + impact: High steps: - material: MetalRod amount: 2 @@ -74,6 +86,10 @@ - node: start edges: - to: spear + completed: + - !type:AdminLog # Needs a log for start of attempt in addition to the completion log + message: "Construction" + impact: High steps: - material: MetalRod amount: 2 @@ -97,6 +113,10 @@ - node: start edges: - to: spear + completed: + - !type:AdminLog # Needs a log for start of attempt in addition to the completion log + message: "Construction" + impact: High steps: - material: Bones amount: 4 diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/bat.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/bat.yml index cecd031f972..2469b31c33a 100644 --- a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/bat.yml +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/bat.yml @@ -23,6 +23,10 @@ - tool: Prying doAfter: 1 - to: bat + completed: + - !type:AdminLog + message: "Construction" + impact: High steps: - tool: Slicing doAfter: 4