"New player" admin logging improvements (#35961)

* Initial commit

* Adjust a whoooole bunch of logs

* Also spears

* Track going crit

* Review fix

* Review fixes
This commit is contained in:
SlamBamActionman
2025-03-20 20:56:51 +01:00
committed by GitHub
parent 07a8a02522
commit 43d08100b9
47 changed files with 249 additions and 97 deletions

View File

@@ -241,7 +241,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
var addedTags = newAccessList.Except(oldTags).Select(tag => "+" + tag).ToList(); var addedTags = newAccessList.Except(oldTags).Select(tag => "+" + tag).ToList();
var removedTags = oldTags.Except(newAccessList).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)}]"); $"{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); accessReaderEnt.Value.Comp.AccessLists = ConvertAccessListToHashSet(newAccessList);

View File

@@ -168,7 +168,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
/*TODO: ECS SharedIdCardConsoleComponent and then log on card ejection, together with the save. /*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*/ 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)}]"); $"{ToPrettyString(player):player} has modified {ToPrettyString(targetId):entity} with the following accesses: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]");
} }

View File

@@ -88,7 +88,7 @@ public sealed class IdCardSystem : SharedIdCardSystem
access.Tags.Add(random.ID); access.Tags.Add(random.ID);
Dirty(uid, access); 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}"); $"{ToPrettyString(args.Microwave)} added {random.ID} access to {ToPrettyString(uid):entity}");
} }

View File

@@ -180,7 +180,7 @@ public sealed class ChangeCvarCommand : IConsoleCommand
var oldValue = _configurationManager.GetCVar<object>(cvar); var oldValue = _configurationManager.GetCVar<object>(cvar);
_configurationManager.SetCVar(cvar, parsed); _configurationManager.SetCVar(cvar, parsed);
_adminLogManager.Add(LogType.AdminCommands, _adminLogManager.Add(LogType.AdminCommands,
LogImpact.High, LogImpact.Extreme,
$"{shell.Player!.Name} ({shell.Player!.UserId}) changed CVAR {cvar} from {oldValue.ToString()} to {parsed.ToString()}" $"{shell.Player!.Name} ({shell.Player!.UserId}) changed CVAR {cvar} from {oldValue.ToString()} to {parsed.ToString()}"
); );

View File

@@ -6,10 +6,14 @@ using Content.Server.Database;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Chat;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Players.PlayTimeTracking;
using Prometheus; using Prometheus;
using Robust.Shared; using Robust.Shared;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Reflection; using Robust.Shared.Reflection;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -25,6 +29,9 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
[Dependency] private readonly IDynamicTypeFactory _typeFactory = default!; [Dependency] private readonly IDynamicTypeFactory _typeFactory = default!;
[Dependency] private readonly IReflectionManager _reflection = default!; [Dependency] private readonly IReflectionManager _reflection = default!;
[Dependency] private readonly IDependencyCollection _dependencies = 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"; public const string SawmillId = "admin.logs";
@@ -66,6 +73,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
private int _queueMax; private int _queueMax;
private int _preRoundQueueMax; private int _preRoundQueueMax;
private int _dropThreshold; private int _dropThreshold;
private int _highImpactLogPlaytime;
// Per update // Per update
private TimeSpan _nextUpdateTime; private TimeSpan _nextUpdateTime;
@@ -100,6 +108,8 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
value => _preRoundQueueMax = value, true); value => _preRoundQueueMax = value, true);
_configuration.OnValueChanged(CCVars.AdminLogsDropThreshold, _configuration.OnValueChanged(CCVars.AdminLogsDropThreshold,
value => _dropThreshold = value, true); value => _dropThreshold = value, true);
_configuration.OnValueChanged(CCVars.AdminLogsHighLogPlaytime,
value => _highImpactLogPlaytime = value, true);
if (_metricsEnabled) if (_metricsEnabled)
{ {
@@ -309,6 +319,21 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
}; };
log.Players.Add(player); 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) if (preRound)

View File

@@ -240,7 +240,7 @@ public sealed class AmeControllerSystem : EntitySystem
return; return;
var humanReadableState = value ? "Inject" : "Not inject"; 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) public void ToggleInjecting(EntityUid uid, EntityUid? user = null, AmeControllerComponent? controller = null)
@@ -267,27 +267,15 @@ public sealed class AmeControllerSystem : EntitySystem
return; return;
var humanReadableState = controller.Injecting ? "Inject" : "Not inject"; 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; var safeLimit = int.MaxValue;
if (TryGetAMENodeGroup(uid, out var group)) if (TryGetAMENodeGroup(uid, out var group))
safeLimit = group.CoreCount * 4; safeLimit = group.CoreCount * 4;
if (oldValue <= safeLimit && value > safeLimit) var logImpact = (oldValue <= safeLimit && value > safeLimit) ? LogImpact.Extreme : LogImpact.Medium;
{
if (_gameTiming.CurTime > controller.EffectCooldown) _adminLogger.Add(LogType.Action, logImpact, $"{EntityManager.ToPrettyString(user.Value):player} has set the AME to inject {controller.InjectionAmount} while set to {humanReadableState}");
{
_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;
}
}
*/
} }
public void AdjustInjectionAmount(EntityUid uid, int delta, EntityUid? user = null, AmeControllerComponent? controller = null) public void AdjustInjectionAmount(EntityUid uid, int delta, EntityUid? user = null, AmeControllerComponent? controller = null)

View File

@@ -116,7 +116,7 @@ public sealed class InnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
_popup.PopupEntity(message, ent, ent, PopupType.MediumCaution); _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); Dirty(ent);
} }

View File

@@ -1,6 +1,7 @@
using Content.Server.Botany.Components; using Content.Server.Botany.Components;
using Content.Server.Botany.Systems; using Content.Server.Botany.Systems;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Database;
using Content.Shared.EntityEffects; using Content.Shared.EntityEffects;
using Content.Shared.Random; using Content.Shared.Random;
using Robust.Shared.Audio; using Robust.Shared.Audio;
@@ -243,6 +244,18 @@ public partial class SeedData
[DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<SeedPrototype>))] [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<SeedPrototype>))]
public List<string> MutationPrototypes = new(); public List<string> MutationPrototypes = new();
/// <summary>
/// Log impact for when the seed is planted.
/// </summary>
[DataField]
public LogImpact? PlantLogImpact = null;
/// <summary>
/// Log impact for when the seed is harvested.
/// </summary>
[DataField]
public LogImpact? HarvestLogImpact = null;
public SeedData Clone() public SeedData Clone()
{ {
DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed."); DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed.");

View File

@@ -14,6 +14,8 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
namespace Content.Server.Botany.Systems; namespace Content.Server.Botany.Systems;
@@ -27,6 +29,7 @@ public sealed partial class BotanySystem : EntitySystem
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly RandomHelperSystem _randomHelper = default!; [Dependency] private readonly RandomHelperSystem _randomHelper = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -116,7 +119,12 @@ public sealed partial class BotanySystem : EntitySystem
{ {
if (position.IsValid(EntityManager) && if (position.IsValid(EntityManager) &&
proto.ProductPrototypes.Count > 0) 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 GenerateProduct(proto, position, yieldMod);
}
return Enumerable.Empty<EntityUid>(); return Enumerable.Empty<EntityUid>();
} }
@@ -131,6 +139,10 @@ public sealed partial class BotanySystem : EntitySystem
var name = Loc.GetString(proto.DisplayName); var name = Loc.GetString(proto.DisplayName);
_popupSystem.PopupCursor(Loc.GetString("botany-harvest-success-message", ("name", name)), user, PopupType.Medium); _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); return GenerateProduct(proto, Transform(user).Coordinates, yieldMod);
} }

View File

@@ -23,7 +23,9 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Content.Server.Labels.Components; using Content.Server.Labels.Components;
using Content.Shared.Administration.Logs;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Content.Shared.Database;
namespace Content.Server.Botany.Systems; namespace Content.Server.Botany.Systems;
@@ -42,6 +44,7 @@ public sealed class PlantHolderSystem : EntitySystem
[Dependency] private readonly RandomHelperSystem _randomHelper = default!; [Dependency] private readonly RandomHelperSystem _randomHelper = default!;
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!; [Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
public const float HydroponicsSpeedMultiplier = 1f; public const float HydroponicsSpeedMultiplier = 1f;
@@ -188,6 +191,9 @@ public sealed class PlantHolderSystem : EntitySystem
CheckLevelSanity(uid, component); CheckLevelSanity(uid, component);
UpdateSprite(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; return;
} }

View File

@@ -82,7 +82,7 @@ public sealed class CursedMaskSystem : SharedCursedMaskSystem
{ {
_mind.TransferTo(ent.Comp.StolenMind.Value, args.Wearer); _mind.TransferTo(ent.Comp.StolenMind.Value, args.Wearer);
_adminLog.Add(LogType.Action, _adminLog.Add(LogType.Action,
LogImpact.Extreme, LogImpact.Medium,
$"{ToPrettyString(args.Wearer):player} was restored to their body after the removal of {ToPrettyString(ent):entity}."); $"{ToPrettyString(args.Wearer):player} was restored to their body after the removal of {ToPrettyString(ent):entity}.");
ent.Comp.StolenMind = null; ent.Comp.StolenMind = null;
} }

View File

@@ -312,7 +312,7 @@ namespace Content.Server.Communications
} }
_roundEndSystem.RequestRoundEnd(uid); _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) private void OnRecallShuttleMessage(EntityUid uid, CommunicationsConsoleComponent comp, CommunicationsConsoleRecallEmergencyShuttleMessage message)
@@ -327,7 +327,7 @@ namespace Content.Server.Communications
} }
_roundEndSystem.CancelRoundEndCountdown(uid); _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.");
} }
} }

View File

@@ -25,7 +25,7 @@ public sealed partial class AdminLog : IGraphAction
var logManager = IoCManager.Resolve<IAdminLogManager>(); var logManager = IoCManager.Resolve<IAdminLogManager>();
if (userUid.HasValue) 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 else
logManager.Add(LogType, Impact, $"{Message} - Entity: {entityManager.ToPrettyString(uid):entity}"); logManager.Add(LogType, Impact, $"{Message} - Entity: {entityManager.ToPrettyString(uid):entity}");
} }

View File

@@ -225,12 +225,12 @@ namespace Content.Server.Decals
if (eventArgs.SenderSession.AttachedEntity != null) 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}"); $"{ToPrettyString(eventArgs.SenderSession.AttachedEntity.Value):actor} drew a {ev.Decal.Color} {ev.Decal.Id} at {ev.Coordinates}");
} }
else 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}"); $"{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) 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}"); $"{ToPrettyString(eventArgs.SenderSession.AttachedEntity.Value):actor} removed a {decal.Color} {decal.Id} at {ev.Coordinates}");
} }
else 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}"); $"{eventArgs.SenderSession.Name} removed a {decal.Color} {decal.Id} at {ev.Coordinates}");
} }

View File

@@ -21,6 +21,8 @@ using Robust.Shared.Containers;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
using System.Linq; using System.Linq;
using Content.Shared.Humanoid;
using Robust.Shared.Player;
namespace Content.Server.Destructible namespace Content.Server.Destructible
{ {
@@ -61,9 +63,12 @@ namespace Content.Server.Destructible
{ {
RaiseLocalEvent(uid, new DamageThresholdReached(component, threshold), true); RaiseLocalEvent(uid, new DamageThresholdReached(component, threshold), true);
var logImpact = LogImpact.Low;
// Convert behaviors into string for logs // Convert behaviors into string for logs
var triggeredBehaviors = string.Join(", ", threshold.Behaviors.Select(b => var triggeredBehaviors = string.Join(", ", threshold.Behaviors.Select(b =>
{ {
if (logImpact <= b.Impact)
logImpact = b.Impact;
if (b is DoActsBehavior doActsBehavior) if (b is DoActsBehavior doActsBehavior)
{ {
return $"{b.GetType().Name}:{doActsBehavior.Acts.ToString()}"; return $"{b.GetType().Name}:{doActsBehavior.Acts.ToString()}";
@@ -71,14 +76,20 @@ namespace Content.Server.Destructible
return b.GetType().Name; return b.GetType().Name;
})); }));
// If it doesn't have a humanoid component, it's probably not particularly notable?
if (logImpact > LogImpact.Medium && !HasComp<HumanoidAppearanceComponent>(uid))
logImpact = LogImpact.Medium;
if (args.Origin != null) 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}]"); $"{ToPrettyString(args.Origin.Value):actor} caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]");
} }
else else
{ {
_adminLogger.Add(LogType.Damaged, LogImpact.Medium, _adminLogger.Add(LogType.Damaged,
logImpact,
$"Unknown damage source caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]"); $"Unknown damage source caused {ToPrettyString(uid):subject} to trigger [{triggeredBehaviors}]");
} }

View File

@@ -1,4 +1,5 @@
using Content.Shared.Body.Components; using Content.Shared.Body.Components;
using Content.Shared.Database;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Content.Server.Destructible.Thresholds.Behaviors namespace Content.Server.Destructible.Thresholds.Behaviors
@@ -9,6 +10,8 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
{ {
[DataField("recursive")] private bool _recursive = true; [DataField("recursive")] private bool _recursive = true;
public LogImpact Impact => LogImpact.Extreme;
public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null) public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
{ {
if (system.EntityManager.TryGetComponent(owner, out BodyComponent? body)) if (system.EntityManager.TryGetComponent(owner, out BodyComponent? body))

View File

@@ -1,7 +1,11 @@
namespace Content.Server.Destructible.Thresholds.Behaviors using Content.Shared.Database;
namespace Content.Server.Destructible.Thresholds.Behaviors
{ {
public interface IThresholdBehavior public interface IThresholdBehavior
{ {
public LogImpact Impact => LogImpact.Low;
/// <summary> /// <summary>
/// Executes this behavior. /// Executes this behavior.
/// </summary> /// </summary>

View File

@@ -256,11 +256,12 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem
} }
else 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); var alertMinExplosionIntensity = _cfg.GetCVar(CCVars.AdminAlertExplosionMinIntensity);
if (alertMinExplosionIntensity > -1 && totalIntensity >= alertMinExplosionIntensity) var logImpact = (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]")}"); ? 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}");
} }
} }

View File

@@ -50,7 +50,7 @@ namespace Content.Server.Explosion.EntitySystems
if (!string.IsNullOrWhiteSpace(component.KeyPhrase) && message.Contains(component.KeyPhrase, StringComparison.InvariantCultureIgnoreCase)) 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}."); $"A voice-trigger on {ToPrettyString(ent):entity} was triggered by {ToPrettyString(args.Source):speaker} speaking the key-phrase {component.KeyPhrase}.");
Trigger(ent, args.Source); Trigger(ent, args.Source);

View File

@@ -7,6 +7,7 @@ using Content.Shared.Damage;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DoAfter; using Content.Shared.DoAfter;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement; using Content.Shared.IdentityManagement;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
@@ -143,7 +144,11 @@ namespace Content.Server.Kitchen.EntitySystems
if (!Resolve(uid, ref component) || !Resolve(victimUid, ref butcherable)) if (!Resolve(uid, ref component) || !Resolve(victimUid, ref butcherable))
return; return;
_logger.Add(LogType.Gib, LogImpact.Extreme, $"{ToPrettyString(userUid):user} kitchen spiked {ToPrettyString(victimUid):target}"); var logImpact = LogImpact.Medium;
if (HasComp<HumanoidAppearanceComponent>(victimUid))
logImpact = LogImpact.Extreme;
_logger.Add(LogType.Gib, logImpact, $"{ToPrettyString(userUid):user} kitchen spiked {ToPrettyString(victimUid):target}");
// TODO VERY SUS // TODO VERY SUS
component.PrototypesToSpawn = EntitySpawnCollection.GetSpawns(butcherable.SpawnedEntities, _random); component.PrototypesToSpawn = EntitySpawnCollection.GetSpawns(butcherable.SpawnedEntities, _random);

View File

@@ -24,6 +24,7 @@ using Robust.Shared.Player;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System.Linq; using System.Linq;
using Content.Shared.Humanoid;
namespace Content.Server.Materials; namespace Content.Server.Materials;
@@ -186,7 +187,8 @@ public sealed class MaterialReclaimerSystem : SharedMaterialReclaimerSystem
if (CanGib(uid, item, component)) if (CanGib(uid, item, component))
{ {
_adminLogger.Add(LogType.Gib, LogImpact.Extreme, $"{ToPrettyString(item):victim} was gibbed by {ToPrettyString(uid):entity} "); var logImpact = HasComp<HumanoidAppearanceComponent>(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); SpawnChemicalsFromComposition(uid, item, completion, false, component, xform);
_body.GibBody(item, true); _body.GibBody(item, true);
_appearance.SetData(uid, RecyclerVisuals.Bloody, true); _appearance.SetData(uid, RecyclerVisuals.Bloody, true);

View File

@@ -182,7 +182,7 @@ namespace Content.Server.Medical.BiomassReclaimer
_throwing.TryThrow(args.Climber, direction, 0.5f); _throwing.TryThrow(args.Climber, direction, 0.5f);
return; 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); StartProcessing(args.Climber, reclaimer);
} }
@@ -195,7 +195,7 @@ namespace Content.Server.Medical.BiomassReclaimer
if (args.Args.Used == null || args.Args.Target == null || !HasComp<BiomassReclaimerComponent>(args.Args.Target.Value)) if (args.Args.Used == null || args.Args.Target == null || !HasComp<BiomassReclaimerComponent>(args.Args.Target.Value))
return; 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); StartProcessing(args.Args.Used.Value, reclaimer);
args.Handled = true; args.Handled = true;

View File

@@ -35,7 +35,7 @@ public sealed class MeteorSystem : EntitySystem
{ {
threshold = mobThreshold.Value; threshold = mobThreshold.Value;
if (HasComp<ActorComponent>(args.OtherEntity)) if (HasComp<ActorComponent>(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)) else if (_destructible.TryGetDestroyedAt(args.OtherEntity, out var destroyThreshold))
{ {

View File

@@ -87,7 +87,7 @@ public sealed class CrematoriumSystem : EntitySystem
Text = Loc.GetString("cremate-verb-get-data-text"), Text = Loc.GetString("cremate-verb-get-data-text"),
// TODO VERB ICON add flame/burn symbol? // TODO VERB ICON add flame/burn symbol?
Act = () => TryCremate(uid, component, storage), 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); args.Verbs.Add(verb);
} }

View File

@@ -195,7 +195,7 @@ public sealed class DrinkSystem : SharedDrinkSystem
_popup.PopupEntity(Loc.GetString("drink-component-force-feed", ("user", userName)), user, target); _popup.PopupEntity(Loc.GetString("drink-component-force-feed", ("user", userName)), user, target);
// logging // 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 else
{ {

View File

@@ -32,13 +32,13 @@ public sealed class PlacementLoggerSystem : EntitySystem
}; };
if (actorEntity != null) 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}"); $"{ToPrettyString(actorEntity.Value):actor} used placement system to {ev.PlacementEventAction.ToString().ToLower()} {ToPrettyString(ev.EditedEntity):subject} at {ev.Coordinates}");
else if (actor != null) 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}"); $"{actor:actor} used placement system to {ev.PlacementEventAction.ToString().ToLower()} {ToPrettyString(ev.EditedEntity):subject} at {ev.Coordinates}");
else 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}"); $"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; var actorEntity = actor?.AttachedEntity;
if (actorEntity != null) 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}"); $"{ToPrettyString(actorEntity.Value):actor} used placement system to set tile {_tileDefinitionManager[ev.TileType].Name} at {ev.Coordinates}");
else if (actor != null) 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}"); $"{actor} used placement system to set tile {_tileDefinitionManager[ev.TileType].Name} at {ev.Coordinates}");
else else
_adminLogger.Add(LogType.Tile, LogImpact.High, _adminLogger.Add(LogType.Tile, LogImpact.Medium,
$"Placement system set tile {_tileDefinitionManager[ev.TileType].Name} at {ev.Coordinates}"); $"Placement system set tile {_tileDefinitionManager[ev.TileType].Name} at {ev.Coordinates}");
} }
} }

View File

@@ -53,7 +53,7 @@ public sealed partial class CableSystem : EntitySystem
if (_electrocutionSystem.TryDoElectrifiedAct(uid, args.User)) if (_electrocutionSystem.TryDoElectrifiedAct(uid, args.User))
return; 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); Spawn(cable.CableDroppedOnCutPrototype, xform.Coordinates);
QueueDel(uid); QueueDel(uid);

View File

@@ -65,7 +65,7 @@ public sealed class ProjectileSystem : SharedProjectileSystem
} }
_adminLogger.Add(LogType.BulletHit, _adminLogger.Add(LogType.BulletHit,
HasComp<ActorComponent>(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"); $"Projectile {ToPrettyString(uid):projectile} shot by {ToPrettyString(component.Shooter!.Value):user} hit {otherName:target} and dealt {modifiedDamage.GetTotal():damage} damage");
} }

View File

@@ -136,7 +136,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
private void Respawn(EntityUid oldEntity, string prototype, EntityCoordinates coords) private void Respawn(EntityUid oldEntity, string prototype, EntityCoordinates coords)
{ {
var entity = Spawn(prototype, 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)}"); _chat.SendAdminAlert($"{MetaData(oldEntity).EntityName} was deleted and was respawned as {ToPrettyString(entity)}");
} }

View File

@@ -372,7 +372,7 @@ public sealed partial class EmergencyShuttleSystem
{ {
if (EarlyLaunchAuthorized || !EmergencyShuttleArrived || _consoleAccumulator <= _authorizeTime) return false; 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; _consoleAccumulator = _authorizeTime;
EarlyLaunchAuthorized = true; EarlyLaunchAuthorized = true;
RaiseLocalEvent(new EmergencyShuttleAuthorizedEvent()); RaiseLocalEvent(new EmergencyShuttleAuthorizedEvent());

View File

@@ -130,7 +130,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
|| _tagSystem.HasTag(morsel, "HighRiskItem") || _tagSystem.HasTag(morsel, "HighRiskItem")
|| HasComp<ContainmentFieldGeneratorComponent>(morsel)) || HasComp<ContainmentFieldGeneratorComponent>(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); EntityManager.QueueDeleteEntity(morsel);

View File

@@ -95,7 +95,7 @@ public sealed class HandTeleporterSystem : EntitySystem
var timeout = EnsureComp<PortalTimeoutComponent>(user); var timeout = EnsureComp<PortalTimeoutComponent>(user);
timeout.EnteredPortal = null; timeout.EnteredPortal = null;
component.FirstPortal = Spawn(component.FirstPortalPrototype, Transform(user).Coordinates); 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); _audio.PlayPvs(component.NewPortalSound, uid);
} }
else if (Deleted(component.SecondPortal)) else if (Deleted(component.SecondPortal))
@@ -113,7 +113,7 @@ public sealed class HandTeleporterSystem : EntitySystem
var timeout = EnsureComp<PortalTimeoutComponent>(user); var timeout = EnsureComp<PortalTimeoutComponent>(user);
timeout.EnteredPortal = null; timeout.EnteredPortal = null;
component.SecondPortal = Spawn(component.SecondPortalPrototype, Transform(user).Coordinates); 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); _link.TryLink(component.FirstPortal!.Value, component.SecondPortal.Value, true);
_audio.PlayPvs(component.NewPortalSound, uid); _audio.PlayPvs(component.NewPortalSound, uid);
} }
@@ -132,7 +132,7 @@ public sealed class HandTeleporterSystem : EntitySystem
portalStrings += " and "; portalStrings += " and ";
portalStrings += ToPrettyString(component.SecondPortal); portalStrings += ToPrettyString(component.SecondPortal);
if (portalStrings != "") 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 // Clear both portals
if (!Deleted(component.FirstPortal)) if (!Deleted(component.FirstPortal))

View File

@@ -4,8 +4,8 @@
[Serializable] [Serializable]
public enum LogImpact : sbyte public enum LogImpact : sbyte
{ {
Low = -1, Low = -1, // General logging
Medium = 0, Medium = 0, // Has impact on the round but not necessary for admins to be notified of
High = 1, High = 1, // Notable logs that come up in normal gameplay; new players causing these will pop up as admin alerts!
Extreme = 2 // Nar'Sie just dropped Extreme = 2 // Irreversible round-impacting logs admins should always be notified of, OR big admin actions!!
} }

View File

@@ -459,4 +459,9 @@ public enum LogType
/// A player was selected or assigned antag status /// A player was selected or assigned antag status
/// </summary> /// </summary>
AntagSelection = 99, AntagSelection = 99,
/// <summary>
/// Logs related to botany, such as planting and harvesting crops
/// </summary>
Botany = 100,
} }

View File

@@ -123,7 +123,7 @@ public abstract class SharedAnomalySystem : EntitySystem
if (HasComp<AnomalySupercriticalComponent>(uid)) if (HasComp<AnomalySupercriticalComponent>(uid))
return; 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) if (_net.IsServer)
Log.Info($"Anomaly is going supercritical. Entity: {ToPrettyString(uid)}"); Log.Info($"Anomaly is going supercritical. Entity: {ToPrettyString(uid)}");

View File

@@ -39,4 +39,11 @@ public sealed partial class CCVars
public static readonly CVarDef<string> AdminLogsServerName = public static readonly CVarDef<string> AdminLogsServerName =
CVarDef.Create("adminlogs.server_name", "unknown", CVar.SERVERONLY); CVarDef.Create("adminlogs.server_name", "unknown", CVar.SERVERONLY);
/// <summary>
/// Any session below this playtime will send an admin alert whenever they cause a LogImpact.High log.
/// Set to -1 to disable.
/// </summary>
public static readonly CVarDef<int> AdminLogsHighLogPlaytime =
CVarDef.Create("adminlogs.high_log_playtime", 5, CVar.SERVERONLY);
} }

View File

@@ -361,7 +361,7 @@ namespace Content.Shared.Cuffs
("otherName", Identity.Name(target, EntityManager, user))), user, user); ("otherName", Identity.Name(target, EntityManager, user))), user, user);
_popup.PopupClient(Loc.GetString("handcuff-component-cuff-by-other-success-message", _popup.PopupClient(Loc.GetString("handcuff-component-cuff-by-other-success-message",
("otherName", Identity.Name(user, EntityManager, target))), target, target); ("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}"); $"{ToPrettyString(user):player} has cuffed {ToPrettyString(target):player}");
} }
} }
@@ -647,7 +647,7 @@ namespace Content.Shared.Cuffs
if (!_doAfter.TryStartDoAfter(doAfterEventArgs)) if (!_doAfter.TryStartDoAfter(doAfterEventArgs))
return; 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 var popupText = user == target
? "cuffable-component-start-uncuffing-self-observer" ? "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", _popup.PopupEntity(Loc.GetString("cuffable-component-remove-cuffs-by-other-success-message",
("otherName", Identity.Name(user.Value, EntityManager, user))), target, target); ("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}"); $"{ToPrettyString(user):player} has successfully uncuffed {ToPrettyString(target):player}");
} }
else else
{ {
_adminLog.Add(LogType.Action, LogImpact.Medium, _adminLog.Add(LogType.Action, LogImpact.High,
$"{ToPrettyString(user):player} has successfully uncuffed themselves"); $"{ToPrettyString(user):player} has successfully uncuffed themselves");
} }
} }

View File

@@ -1,5 +1,7 @@
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Humanoid;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Robust.Shared.Player;
namespace Content.Shared.Mobs.Systems; namespace Content.Shared.Mobs.Systems;
@@ -110,8 +112,10 @@ public partial class MobStateSystem
var ev = new MobStateChangedEvent(target, component, oldState, newState, origin); var ev = new MobStateChangedEvent(target, component, oldState, newState, origin);
OnStateChanged(target, component, oldState, newState); OnStateChanged(target, component, oldState, newState);
RaiseLocalEvent(target, ev, true); RaiseLocalEvent(target, ev, true);
_adminLogger.Add(LogType.Damaged, oldState == MobState.Alive ? LogImpact.Low : LogImpact.Medium, if (origin != null && HasComp<ActorComponent>(origin) && HasComp<ActorComponent>(target) && oldState < newState)
$"{ToPrettyString(target):user} state changed from {oldState} to {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); Dirty(target, component);
} }

View File

@@ -251,14 +251,14 @@ public abstract class SharedRoleSystem : EntitySystem
else else
{ {
var error = $"The Character Window of {_minds.MindOwnerLoggingString(comp)} potentially did not update immediately : session error"; 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) if (comp.OwnedEntity is null)
{ {
Log.Error($"{ToPrettyString(mind)} does not have an OwnedEntity!"); Log.Error($"{ToPrettyString(mind)} does not have an OwnedEntity!");
_adminLogger.Add(LogType.Mind, _adminLogger.Add(LogType.Mind,
LogImpact.High, LogImpact.Medium,
$"Role Type of {ToPrettyString(mind)} changed to {roleTypeId}"); $"Role Type of {ToPrettyString(mind)} changed to {roleTypeId}");
return; return;
} }

View File

@@ -339,7 +339,7 @@ public abstract class SharedStrippableSystem : EntitySystem
RaiseLocalEvent(item, new DroppedEvent(user), true); // Gas tank internals etc. RaiseLocalEvent(item, new DroppedEvent(user), true); // Gas tank internals etc.
_handsSystem.PickupOrDrop(user, item, animateUser: stealth, animate: !stealth); _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");
} }
/// <summary> /// <summary>
@@ -544,7 +544,7 @@ public abstract class SharedStrippableSystem : EntitySystem
_handsSystem.TryDrop(target, item, checkActionBlocker: false, handsComp: target.Comp); _handsSystem.TryDrop(target, item, checkActionBlocker: false, handsComp: target.Comp);
_handsSystem.PickupOrDrop(user, item, animateUser: stealth, animate: !stealth, handsComp: user.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. // Hand update will trigger strippable update.
} }

View File

@@ -49,7 +49,7 @@ chat-manager-dead-channel-name = DEAD
chat-manager-admin-channel-name = ADMIN chat-manager-admin-channel-name = ADMIN
chat-manager-rate-limited = You are sending messages too quickly! 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 ## Speech verbs for chat

View File

@@ -622,6 +622,8 @@
noun: seeds-noun-seeds noun: seeds-noun-seeds
displayName: seeds-killertomato-display-name displayName: seeds-killertomato-display-name
plantRsi: Objects/Specific/Hydroponics/tomatokiller.rsi plantRsi: Objects/Specific/Hydroponics/tomatokiller.rsi
plantLogImpact: High
harvestLogImpact: High
packetPrototype: KillerTomatoSeeds packetPrototype: KillerTomatoSeeds
productPrototypes: productPrototypes:
- MobTomatoKiller - MobTomatoKiller
@@ -1063,6 +1065,8 @@
displayName: seeds-deathnettle-display-name displayName: seeds-deathnettle-display-name
plantRsi: Objects/Specific/Hydroponics/death_nettle.rsi plantRsi: Objects/Specific/Hydroponics/death_nettle.rsi
packetPrototype: DeathNettleSeeds packetPrototype: DeathNettleSeeds
plantLogImpact: High
harvestLogImpact: High
productPrototypes: productPrototypes:
- DeathNettle - DeathNettle
lifespan: 25 lifespan: 25

View File

@@ -2,26 +2,29 @@
id: MeatSpike id: MeatSpike
start: start start: start
graph: graph:
- node: start - node: start
actions: actions:
- !type:DeleteEntity {} - !type:DeleteEntity {}
edges: edges:
- to: MeatSpike - to: MeatSpike
completed: completed:
- !type:SnapToGrid - !type:AdminLog # Needs a log for start of attempt in addition to the completion log
southRotation: true message: "Construction"
steps: impact: High
- material: Steel - !type:SnapToGrid
amount: 15 southRotation: true
doAfter: 2 steps:
- node: MeatSpike - material: Steel
entity: KitchenSpike amount: 15
edges: doAfter: 2
- to: start - node: MeatSpike
completed: entity: KitchenSpike
- !type:SpawnPrototype edges:
prototype: SheetSteel1 - to: start
amount: 15 completed:
steps: - !type:SpawnPrototype
- tool: Screwing prototype: SheetSteel1
doAfter: 1 amount: 15
steps:
- tool: Screwing
doAfter: 1

View File

@@ -6,6 +6,9 @@
edges: edges:
- to: grille - to: grille
completed: completed:
- !type:AdminLog # Needs a log for start of attempt in addition to the completion log
message: "Construction"
impact: High
- !type:SnapToGrid - !type:SnapToGrid
southRotation: true southRotation: true
steps: steps:

View File

@@ -6,6 +6,10 @@
entity: ShardGlass entity: ShardGlass
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- material: Cloth - material: Cloth
amount: 1 amount: 1
@@ -20,6 +24,10 @@
- node: start - node: start
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- tag: GlassShard - tag: GlassShard
name: glass shard name: glass shard
@@ -41,6 +49,10 @@
entity: ShardGlassReinforced entity: ShardGlassReinforced
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- material: Cloth - material: Cloth
amount: 1 amount: 1
@@ -55,6 +67,10 @@
- node: start - node: start
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- tag: ReinforcedGlassShard - tag: ReinforcedGlassShard
name: reinforced glass shard name: reinforced glass shard
@@ -76,6 +92,10 @@
entity: ShardGlassPlasma entity: ShardGlassPlasma
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- material: Cloth - material: Cloth
amount: 1 amount: 1
@@ -90,6 +110,10 @@
- node: start - node: start
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- tag: PlasmaGlassShard - tag: PlasmaGlassShard
name: plasma glass shard name: plasma glass shard
@@ -111,6 +135,10 @@
entity: ShardGlassUranium entity: ShardGlassUranium
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- material: Cloth - material: Cloth
amount: 1 amount: 1
@@ -125,6 +153,10 @@
- node: start - node: start
edges: edges:
- to: icon - to: icon
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- tag: UraniumGlassShard - tag: UraniumGlassShard
name: uranium glass shard name: uranium glass shard

View File

@@ -5,6 +5,10 @@
- node: start - node: start
edges: edges:
- to: spear - to: spear
completed:
- !type:AdminLog # Needs a log for start of attempt in addition to the completion log
message: "Construction"
impact: High
steps: steps:
- material: MetalRod - material: MetalRod
amount: 2 amount: 2
@@ -28,6 +32,10 @@
- node: start - node: start
edges: edges:
- to: spear - to: spear
completed:
- !type:AdminLog # Needs a log for start of attempt in addition to the completion log
message: "Construction"
impact: High
steps: steps:
- material: MetalRod - material: MetalRod
amount: 2 amount: 2
@@ -51,6 +59,10 @@
- node: start - node: start
edges: edges:
- to: spear - to: spear
completed:
- !type:AdminLog # Needs a log for start of attempt in addition to the completion log
message: "Construction"
impact: High
steps: steps:
- material: MetalRod - material: MetalRod
amount: 2 amount: 2
@@ -74,6 +86,10 @@
- node: start - node: start
edges: edges:
- to: spear - to: spear
completed:
- !type:AdminLog # Needs a log for start of attempt in addition to the completion log
message: "Construction"
impact: High
steps: steps:
- material: MetalRod - material: MetalRod
amount: 2 amount: 2
@@ -97,6 +113,10 @@
- node: start - node: start
edges: edges:
- to: spear - to: spear
completed:
- !type:AdminLog # Needs a log for start of attempt in addition to the completion log
message: "Construction"
impact: High
steps: steps:
- material: Bones - material: Bones
amount: 4 amount: 4

View File

@@ -23,6 +23,10 @@
- tool: Prying - tool: Prying
doAfter: 1 doAfter: 1
- to: bat - to: bat
completed:
- !type:AdminLog
message: "Construction"
impact: High
steps: steps:
- tool: Slicing - tool: Slicing
doAfter: 4 doAfter: 4