Make pow3r validation logic available on release (#36075)
I want to run this on live servers. It's behind a power_validate command, it still doesn't automatically get ran outside debug otherwise.
This commit is contained in:
committed by
GitHub
parent
9243d65e6f
commit
290bffceec
29
Content.Server/Power/Commands/PowerValidateCommand.cs
Normal file
29
Content.Server/Power/Commands/PowerValidateCommand.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using Content.Server.Administration;
|
||||||
|
using Content.Server.Power.EntitySystems;
|
||||||
|
using Content.Shared.Administration;
|
||||||
|
using Robust.Shared.Console;
|
||||||
|
|
||||||
|
namespace Content.Server.Power.Commands;
|
||||||
|
|
||||||
|
[AdminCommand(AdminFlags.Debug)]
|
||||||
|
public sealed class PowerValidateCommand : LocalizedEntityCommands
|
||||||
|
{
|
||||||
|
[Dependency] private readonly PowerNetSystem _powerNet = null!;
|
||||||
|
|
||||||
|
public override string Command => "power_validate";
|
||||||
|
|
||||||
|
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_powerNet.Validate();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
shell.WriteLine(LocalizationManager.GetString("cmd-power_validate-error", ("err", e.ToString())));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shell.WriteLine(LocalizationManager.GetString("cmd-power_validate-success"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -519,6 +519,14 @@ namespace Content.Server.Power.EntitySystems
|
|||||||
supplier.NetworkSupply.LinkedNetwork = netNode.Id;
|
supplier.NetworkSupply.LinkedNetwork = netNode.Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validate integrity of the power state data. Throws if an error is found.
|
||||||
|
/// </summary>
|
||||||
|
public void Validate()
|
||||||
|
{
|
||||||
|
_solver.Validate(_powerState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Threading;
|
using Robust.Shared.Threading;
|
||||||
using static Content.Server.Power.Pow3r.PowerState;
|
using static Content.Server.Power.Pow3r.PowerState;
|
||||||
|
|
||||||
@@ -40,7 +42,9 @@ namespace Content.Server.Power.Pow3r
|
|||||||
DebugTools.Assert(state.GroupedNets.Select(x => x.Count).Sum() == state.Networks.Count);
|
DebugTools.Assert(state.GroupedNets.Select(x => x.Count).Sum() == state.Networks.Count);
|
||||||
_networkJob.State = state;
|
_networkJob.State = state;
|
||||||
_networkJob.FrameTime = frameTime;
|
_networkJob.FrameTime = frameTime;
|
||||||
|
#if DEBUG
|
||||||
ValidateNetworkGroups(state, state.GroupedNets);
|
ValidateNetworkGroups(state, state.GroupedNets);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Each network height layer can be run in parallel without issues.
|
// Each network height layer can be run in parallel without issues.
|
||||||
foreach (var group in state.GroupedNets)
|
foreach (var group in state.GroupedNets)
|
||||||
@@ -328,16 +332,22 @@ namespace Content.Server.Power.Pow3r
|
|||||||
RecursivelyEstimateNetworkDepth(state, network, groupedNetworks);
|
RecursivelyEstimateNetworkDepth(state, network, groupedNetworks);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateNetworkGroups(state, groupedNetworks);
|
|
||||||
return groupedNetworks;
|
return groupedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Validate(PowerState state)
|
||||||
|
{
|
||||||
|
if (state.GroupedNets == null)
|
||||||
|
throw new InvalidOperationException("We don't have grouped networks cached??");
|
||||||
|
|
||||||
|
ValidateNetworkGroups(state, state.GroupedNets);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validate that network grouping is up to date. I.e., that it is safe to solve each networking in a given
|
/// Validate that network grouping is up to date. I.e., that it is safe to solve each networking in a given
|
||||||
/// group in parallel. This assumes that batteries are the only device that connects to multiple networks, and
|
/// group in parallel. This assumes that batteries are the only device that connects to multiple networks, and
|
||||||
/// is thus the only obstacle to solving everything in parallel.
|
/// is thus the only obstacle to solving everything in parallel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Conditional("DEBUG")]
|
|
||||||
private void ValidateNetworkGroups(PowerState state, List<List<Network>> groupedNetworks)
|
private void ValidateNetworkGroups(PowerState state, List<List<Network>> groupedNetworks)
|
||||||
{
|
{
|
||||||
HashSet<Network> nets = new();
|
HashSet<Network> nets = new();
|
||||||
@@ -362,9 +372,9 @@ namespace Content.Server.Power.Pow3r
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugTools.Assert(!nets.Contains(subNet));
|
Check(!nets.Contains(subNet), $"Net {net.Id}, battery {batteryId}");
|
||||||
DebugTools.Assert(!netIds.Contains(subNet.Id));
|
Check(!netIds.Contains(subNet.Id), $"Net {net.Id}, battery {batteryId}");
|
||||||
DebugTools.Assert(subNet.Height < net.Height);
|
Check(subNet.Height < net.Height, $"Net {net.Id}, battery {batteryId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var batteryId in net.BatterySupplies)
|
foreach (var batteryId in net.BatterySupplies)
|
||||||
@@ -380,15 +390,32 @@ namespace Content.Server.Power.Pow3r
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugTools.Assert(!nets.Contains(parentNet));
|
Check(!nets.Contains(parentNet), $"Net {net.Id}, battery {batteryId}");
|
||||||
DebugTools.Assert(!netIds.Contains(parentNet.Id));
|
Check(!netIds.Contains(parentNet.Id), $"Net {net.Id}, battery {batteryId}");
|
||||||
DebugTools.Assert(parentNet.Height > net.Height);
|
Check(parentNet.Height > net.Height, $"Net {net.Id}, battery {batteryId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugTools.Assert(nets.Add(net));
|
Check(nets.Add(net), $"Net {net.Id}");
|
||||||
DebugTools.Assert(netIds.Add(net.Id));
|
Check(netIds.Add(net.Id), $"Net {net.Id}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Most readable C# function def.
|
||||||
|
[AssertionMethod]
|
||||||
|
static void Check(
|
||||||
|
[AssertionCondition(AssertionConditionType.IS_TRUE)]
|
||||||
|
[DoesNotReturnIf(false)]
|
||||||
|
bool condition,
|
||||||
|
[InterpolatedStringHandlerArgument("condition")]
|
||||||
|
ref DebugTools.AssertInterpolatedStringHandler handler,
|
||||||
|
[CallerArgumentExpression(nameof(condition))]
|
||||||
|
string check = "")
|
||||||
|
{
|
||||||
|
if (!condition)
|
||||||
|
throw new DebugAssertException($"{handler.ToStringAndClear()}: failed check: {check}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RecursivelyEstimateNetworkDepth(PowerState state, Network network, List<List<Network>> groupedNetworks)
|
private static void RecursivelyEstimateNetworkDepth(PowerState state, Network network, List<List<Network>> groupedNetworks)
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ namespace Content.Server.Power.Pow3r
|
|||||||
public interface IPowerSolver
|
public interface IPowerSolver
|
||||||
{
|
{
|
||||||
void Tick(float frameTime, PowerState state, IParallelManager parallel);
|
void Tick(float frameTime, PowerState state, IParallelManager parallel);
|
||||||
|
void Validate(PowerState state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,10 @@ namespace Content.Server.Power.Pow3r
|
|||||||
{
|
{
|
||||||
// Literally nothing.
|
// Literally nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Validate(PowerState state)
|
||||||
|
{
|
||||||
|
// Literally nothing.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
Resources/Locale/en-US/power/commands.ftl
Normal file
4
Resources/Locale/en-US/power/commands.ftl
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
cmd-power_validate-desc = Validate power network state integrity
|
||||||
|
cmd-power_validate-help = Usage: power_validate
|
||||||
|
cmd-power_validate-error = Error while validating: { $err }
|
||||||
|
cmd-power_validate-success = Validation succeeded without error
|
||||||
Reference in New Issue
Block a user