Add air alarm admin logs (#33426)
This commit is contained in:
@@ -9,10 +9,12 @@ using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Monitor.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceLinking;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
@@ -37,6 +39,7 @@ namespace Content.Server.Atmos.Monitor.Systems;
|
||||
public sealed class AirAlarmSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AccessReaderSystem _access = default!;
|
||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!;
|
||||
[Dependency] private readonly AtmosDeviceNetworkSystem _atmosDevNet = default!;
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNet = default!;
|
||||
@@ -296,6 +299,7 @@ public sealed class AirAlarmSystem : EntitySystem
|
||||
addr = netConn.Address;
|
||||
}
|
||||
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(args.Actor)} changed {ToPrettyString(uid)} mode to {args.Mode}");
|
||||
SetMode(uid, addr, args.Mode, false);
|
||||
}
|
||||
else
|
||||
@@ -307,15 +311,26 @@ public sealed class AirAlarmSystem : EntitySystem
|
||||
private void OnUpdateAutoMode(EntityUid uid, AirAlarmComponent component, AirAlarmUpdateAutoModeMessage args)
|
||||
{
|
||||
component.AutoMode = args.Enabled;
|
||||
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(args.Actor)} changed {ToPrettyString(uid)} auto mode to {args.Enabled}");
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
|
||||
private void OnUpdateThreshold(EntityUid uid, AirAlarmComponent component, AirAlarmUpdateAlarmThresholdMessage args)
|
||||
{
|
||||
if (AccessCheck(uid, args.Actor, component))
|
||||
{
|
||||
if (args.Gas != null)
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(args.Actor)} changed {args.Address} {args.Gas} {args.Type} threshold using {ToPrettyString(uid)}");
|
||||
else
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(args.Actor)} changed {args.Address} {args.Type} threshold using {ToPrettyString(uid)}");
|
||||
|
||||
SetThreshold(uid, args.Address, args.Type, args.Threshold, args.Gas);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUpdateDeviceData(EntityUid uid, AirAlarmComponent component, AirAlarmUpdateDeviceDataMessage args)
|
||||
@@ -323,6 +338,8 @@ public sealed class AirAlarmSystem : EntitySystem
|
||||
if (AccessCheck(uid, args.Actor, component)
|
||||
&& _deviceList.ExistsInDeviceList(uid, args.Address))
|
||||
{
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(args.Actor)} changed {args.Address} settings using {ToPrettyString(uid)}");
|
||||
|
||||
SetDeviceData(uid, args.Address, args.Data);
|
||||
}
|
||||
else
|
||||
@@ -344,6 +361,7 @@ public sealed class AirAlarmSystem : EntitySystem
|
||||
case GasVentPumpData ventData:
|
||||
foreach (string addr in component.VentData.Keys)
|
||||
{
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(args.Actor)} copied settings to vent {addr}");
|
||||
SetData(uid, addr, args.Data);
|
||||
}
|
||||
break;
|
||||
@@ -351,6 +369,7 @@ public sealed class AirAlarmSystem : EntitySystem
|
||||
case GasVentScrubberData scrubberData:
|
||||
foreach (string addr in component.ScrubberData.Keys)
|
||||
{
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(args.Actor)} copied settings to scrubber {addr}");
|
||||
SetData(uid, addr, args.Data);
|
||||
}
|
||||
break;
|
||||
@@ -379,6 +398,7 @@ public sealed class AirAlarmSystem : EntitySystem
|
||||
if (!_access.IsAllowed(user.Value, uid, reader))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("air-alarm-ui-access-denied"), user.Value, user.Value);
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Low, $"{ToPrettyString(user)} attempted to access {ToPrettyString(uid)} without access");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,11 @@ using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Piping.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Tag;
|
||||
@@ -25,6 +27,7 @@ namespace Content.Server.Atmos.Monitor.Systems;
|
||||
// a danger), and atmos (which triggers based on set thresholds).
|
||||
public sealed class AtmosMonitorSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
[Dependency] private readonly AtmosDeviceSystem _atmosDeviceSystem = default!;
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
|
||||
@@ -393,21 +396,74 @@ public sealed class AtmosMonitorSystem : EntitySystem
|
||||
if (!Resolve(uid, ref monitor))
|
||||
return;
|
||||
|
||||
// Used for logging after the switch statement
|
||||
string logPrefix = "";
|
||||
string logValueSuffix = "";
|
||||
AtmosAlarmThreshold? logPreviousThreshold = null;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case AtmosMonitorThresholdType.Pressure:
|
||||
logPrefix = "pressure";
|
||||
logValueSuffix = "kPa";
|
||||
logPreviousThreshold = monitor.PressureThreshold;
|
||||
|
||||
monitor.PressureThreshold = threshold;
|
||||
break;
|
||||
case AtmosMonitorThresholdType.Temperature:
|
||||
logPrefix = "temperature";
|
||||
logValueSuffix = "K";
|
||||
logPreviousThreshold = monitor.TemperatureThreshold;
|
||||
|
||||
monitor.TemperatureThreshold = threshold;
|
||||
break;
|
||||
case AtmosMonitorThresholdType.Gas:
|
||||
if (gas == null || monitor.GasThresholds == null)
|
||||
return;
|
||||
|
||||
logPrefix = ((Gas) gas).ToString();
|
||||
logValueSuffix = "kPa";
|
||||
monitor.GasThresholds.TryGetValue((Gas) gas, out logPreviousThreshold);
|
||||
|
||||
monitor.GasThresholds[(Gas) gas] = threshold;
|
||||
break;
|
||||
}
|
||||
|
||||
// Admin log each change separately rather than logging the whole state
|
||||
if (logPreviousThreshold != null)
|
||||
{
|
||||
if (threshold.Ignore != logPreviousThreshold.Ignore)
|
||||
{
|
||||
string enabled = threshold.Ignore ? "disabled" : "enabled";
|
||||
_adminLogger.Add(
|
||||
LogType.AtmosDeviceSetting,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(uid)} {logPrefix} thresholds {enabled}"
|
||||
);
|
||||
}
|
||||
|
||||
foreach (var change in threshold.GetChanges(logPreviousThreshold))
|
||||
{
|
||||
if (change.Current.Enabled != change.Previous?.Enabled)
|
||||
{
|
||||
string enabled = change.Current.Enabled ? "enabled" : "disabled";
|
||||
_adminLogger.Add(
|
||||
LogType.AtmosDeviceSetting,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(uid)} {logPrefix} {change.Type} {enabled}"
|
||||
);
|
||||
}
|
||||
|
||||
if (change.Current.Value != change.Previous?.Value)
|
||||
{
|
||||
_adminLogger.Add(
|
||||
LogType.AtmosDeviceSetting,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(uid)} {logPrefix} {change.Type} changed from {change.Previous?.Value} {logValueSuffix} to {change.Current.Value} {logValueSuffix}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -9,6 +9,7 @@ using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Piping.Components;
|
||||
@@ -16,6 +17,7 @@ using Content.Shared.Atmos.Piping.Unary;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Atmos.Visuals;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Examine;
|
||||
@@ -30,6 +32,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
[UsedImplicitly]
|
||||
public sealed class GasVentPumpSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
|
||||
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
|
||||
@@ -232,6 +235,44 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
if (!args.Data.TryGetValue(DeviceNetworkConstants.CmdSetState, out GasVentPumpData? setData))
|
||||
break;
|
||||
|
||||
var previous = component.ToAirAlarmData();
|
||||
|
||||
if (previous.Enabled != setData.Enabled)
|
||||
{
|
||||
string enabled = setData.Enabled ? "enabled" : "disabled" ;
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} {enabled}");
|
||||
}
|
||||
|
||||
if (previous.PumpDirection != setData.PumpDirection)
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} direction changed to {setData.PumpDirection}");
|
||||
|
||||
if (previous.PressureChecks != setData.PressureChecks)
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} pressure check changed to {setData.PressureChecks}");
|
||||
|
||||
if (previous.ExternalPressureBound != setData.ExternalPressureBound)
|
||||
{
|
||||
_adminLogger.Add(
|
||||
LogType.AtmosDeviceSetting,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(uid)} external pressure bound changed from {previous.ExternalPressureBound} kPa to {setData.ExternalPressureBound} kPa"
|
||||
);
|
||||
}
|
||||
|
||||
if (previous.InternalPressureBound != setData.InternalPressureBound)
|
||||
{
|
||||
_adminLogger.Add(
|
||||
LogType.AtmosDeviceSetting,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(uid)} internal pressure bound changed from {previous.InternalPressureBound} kPa to {setData.InternalPressureBound} kPa"
|
||||
);
|
||||
}
|
||||
|
||||
if (previous.PressureLockoutOverride != setData.PressureLockoutOverride)
|
||||
{
|
||||
string enabled = setData.PressureLockoutOverride ? "enabled" : "disabled" ;
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} pressure lockout override {enabled}");
|
||||
}
|
||||
|
||||
component.FromAirAlarmData(setData);
|
||||
UpdateState(uid, component);
|
||||
|
||||
|
||||
@@ -10,12 +10,14 @@ using Content.Server.NodeContainer;
|
||||
using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.NodeContainer.Nodes;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Piping.Unary.Visuals;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Piping.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.DeviceNetwork;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Tools.Systems;
|
||||
@@ -27,6 +29,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
[UsedImplicitly]
|
||||
public sealed class GasVentScrubberSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
[Dependency] private readonly DeviceNetworkSystem _deviceNetSystem = default!;
|
||||
[Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
|
||||
@@ -163,6 +166,43 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
|
||||
if (!args.Data.TryGetValue(DeviceNetworkConstants.CmdSetState, out GasVentScrubberData? setData))
|
||||
break;
|
||||
|
||||
var previous = component.ToAirAlarmData();
|
||||
|
||||
if (previous.Enabled != setData.Enabled)
|
||||
{
|
||||
string enabled = setData.Enabled ? "enabled" : "disabled" ;
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} {enabled}");
|
||||
}
|
||||
|
||||
// TODO: IgnoreAlarms?
|
||||
|
||||
if (previous.PumpDirection != setData.PumpDirection)
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} direction changed to {setData.PumpDirection}");
|
||||
|
||||
// TODO: This is iterating through both sets, it could probably be faster but they're both really small sets anyways
|
||||
foreach (Gas gas in previous.FilterGases)
|
||||
if (!setData.FilterGases.Contains(gas))
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} {gas} filtering disabled");
|
||||
|
||||
foreach (Gas gas in setData.FilterGases)
|
||||
if (!previous.FilterGases.Contains(gas))
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} {gas} filtering enabled");
|
||||
|
||||
if (previous.VolumeRate != setData.VolumeRate)
|
||||
{
|
||||
_adminLogger.Add(
|
||||
LogType.AtmosDeviceSetting,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(uid)} volume rate changed from {previous.VolumeRate} L to {setData.VolumeRate} L"
|
||||
);
|
||||
}
|
||||
|
||||
if (previous.WideNet != setData.WideNet)
|
||||
{
|
||||
string enabled = setData.WideNet ? "enabled" : "disabled" ;
|
||||
_adminLogger.Add(LogType.AtmosDeviceSetting, LogImpact.Medium, $"{ToPrettyString(uid)} WideNet {enabled}");
|
||||
}
|
||||
|
||||
component.FromAirAlarmData(setData);
|
||||
UpdateState(uid, component);
|
||||
|
||||
|
||||
@@ -444,4 +444,9 @@ public enum LogType
|
||||
/// A player interacted with a PDA or its cartridge component
|
||||
/// </summary>
|
||||
PdaInteract = 96,
|
||||
|
||||
/// <summary>
|
||||
/// An atmos networked device (such as a vent or pump) has had its settings changed, usually through an air alarm
|
||||
/// </summary>
|
||||
AtmosDeviceSetting = 97,
|
||||
}
|
||||
|
||||
@@ -253,10 +253,57 @@ public sealed partial class AtmosAlarmThreshold
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Iterates through the changes that these threshold settings would make from a
|
||||
/// previous instance. Basically, diffs the two settings.
|
||||
/// </summary>
|
||||
public IEnumerable<AtmosAlarmThresholdChange> GetChanges(AtmosAlarmThreshold previous)
|
||||
{
|
||||
if (LowerBound != previous.LowerBound)
|
||||
yield return new AtmosAlarmThresholdChange(AtmosMonitorLimitType.LowerDanger, previous.LowerBound, LowerBound);
|
||||
|
||||
if (LowerWarningBound != previous.LowerWarningBound)
|
||||
yield return new AtmosAlarmThresholdChange(AtmosMonitorLimitType.LowerWarning, previous.LowerWarningBound, LowerWarningBound);
|
||||
|
||||
if (UpperBound != previous.UpperBound)
|
||||
yield return new AtmosAlarmThresholdChange(AtmosMonitorLimitType.UpperDanger, previous.UpperBound, UpperBound);
|
||||
|
||||
if (UpperWarningBound != previous.UpperWarningBound)
|
||||
yield return new AtmosAlarmThresholdChange(AtmosMonitorLimitType.UpperWarning, previous.UpperWarningBound, UpperWarningBound);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A change of a single value between two AtmosAlarmThreshold, for a given AtmosMonitorLimitType
|
||||
/// </summary>
|
||||
public readonly struct AtmosAlarmThresholdChange
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of change between the two threshold sets
|
||||
/// </summary>
|
||||
public readonly AtmosMonitorLimitType Type;
|
||||
|
||||
/// <summary>
|
||||
/// The value in the old threshold set
|
||||
/// </summary>
|
||||
public readonly AlarmThresholdSetting? Previous;
|
||||
|
||||
/// <summary>
|
||||
/// The value in the new threshold set
|
||||
/// </summary>
|
||||
public readonly AlarmThresholdSetting Current;
|
||||
|
||||
public AtmosAlarmThresholdChange(AtmosMonitorLimitType type, AlarmThresholdSetting? previous, AlarmThresholdSetting current)
|
||||
{
|
||||
Type = type;
|
||||
Previous = previous;
|
||||
Current = current;
|
||||
}
|
||||
}
|
||||
|
||||
[DataDefinition, Serializable]
|
||||
public readonly partial struct AlarmThresholdSetting
|
||||
public readonly partial struct AlarmThresholdSetting: IEquatable<AlarmThresholdSetting>
|
||||
{
|
||||
[DataField("enabled")]
|
||||
public bool Enabled { get; init; } = true;
|
||||
@@ -289,6 +336,32 @@ public readonly partial struct AlarmThresholdSetting
|
||||
{
|
||||
return this with {Enabled = enabled};
|
||||
}
|
||||
|
||||
public bool Equals(AlarmThresholdSetting other)
|
||||
{
|
||||
if (Enabled != other.Enabled)
|
||||
return false;
|
||||
|
||||
if (Value != other.Value)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator ==(AlarmThresholdSetting lhs, AlarmThresholdSetting rhs)
|
||||
{
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
|
||||
public static bool operator !=(AlarmThresholdSetting lhs, AlarmThresholdSetting rhs)
|
||||
{
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Enabled, Value);
|
||||
}
|
||||
}
|
||||
|
||||
public enum AtmosMonitorThresholdBound
|
||||
|
||||
Reference in New Issue
Block a user