"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:
@@ -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);
|
||||
|
||||
@@ -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)}]");
|
||||
}
|
||||
|
||||
|
||||
@@ -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}");
|
||||
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ public sealed class ChangeCvarCommand : IConsoleCommand
|
||||
var oldValue = _configurationManager.GetCVar<object>(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()}"
|
||||
);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<SeedPrototype>))]
|
||||
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()
|
||||
{
|
||||
DebugTools.Assert(!Immutable, "There should be no need to clone an immutable seed.");
|
||||
|
||||
@@ -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<EntityUid>();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed partial class AdminLog : IGraphAction
|
||||
var logManager = IoCManager.Resolve<IAdminLogManager>();
|
||||
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
|
||||
|
||||
@@ -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<HumanoidAppearanceComponent>(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}]");
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Executes this behavior.
|
||||
/// </summary>
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<HumanoidAppearanceComponent>(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);
|
||||
|
||||
@@ -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<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);
|
||||
_body.GibBody(item, true);
|
||||
_appearance.SetData(uid, RecyclerVisuals.Bloody, true);
|
||||
|
||||
@@ -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<BiomassReclaimerComponent>(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;
|
||||
|
||||
@@ -35,7 +35,7 @@ public sealed class MeteorSystem : EntitySystem
|
||||
{
|
||||
threshold = mobThreshold.Value;
|
||||
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))
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -65,7 +65,7 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
||||
}
|
||||
|
||||
_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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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)}");
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -130,7 +130,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
|
||||
|| _tagSystem.HasTag(morsel, "HighRiskItem")
|
||||
|| 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);
|
||||
|
||||
@@ -95,7 +95,7 @@ public sealed class HandTeleporterSystem : EntitySystem
|
||||
var timeout = EnsureComp<PortalTimeoutComponent>(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<PortalTimeoutComponent>(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))
|
||||
|
||||
@@ -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!!
|
||||
}
|
||||
|
||||
@@ -459,4 +459,9 @@ public enum LogType
|
||||
/// A player was selected or assigned antag status
|
||||
/// </summary>
|
||||
AntagSelection = 99,
|
||||
|
||||
/// <summary>
|
||||
/// Logs related to botany, such as planting and harvesting crops
|
||||
/// </summary>
|
||||
Botany = 100,
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public abstract class SharedAnomalySystem : EntitySystem
|
||||
if (HasComp<AnomalySupercriticalComponent>(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)}");
|
||||
|
||||
|
||||
@@ -39,4 +39,11 @@ public sealed partial class CCVars
|
||||
|
||||
public static readonly CVarDef<string> AdminLogsServerName =
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ActorComponent>(origin) && HasComp<ActorComponent>(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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
- tool: Prying
|
||||
doAfter: 1
|
||||
- to: bat
|
||||
completed:
|
||||
- !type:AdminLog
|
||||
message: "Construction"
|
||||
impact: High
|
||||
steps:
|
||||
- tool: Slicing
|
||||
doAfter: 4
|
||||
|
||||
Reference in New Issue
Block a user