diff --git a/Content.Server/Administration/AdminCommandAttribute.cs b/Content.Server/Administration/AdminCommandAttribute.cs index 0c9730df82..b7e17c9c4d 100644 --- a/Content.Server/Administration/AdminCommandAttribute.cs +++ b/Content.Server/Administration/AdminCommandAttribute.cs @@ -12,7 +12,7 @@ namespace Content.Server.Administration /// If this attribute is used multiple times, either attribute's flag sets can be used to get access. /// /// - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] [BaseTypeRequired(typeof(IConsoleCommand))] [MeansImplicitUse] public sealed class AdminCommandAttribute : Attribute diff --git a/Content.Server/Administration/Managers/AdminManager.cs b/Content.Server/Administration/Managers/AdminManager.cs index cd88ac315f..c554750371 100644 --- a/Content.Server/Administration/Managers/AdminManager.cs +++ b/Content.Server/Administration/Managers/AdminManager.cs @@ -436,7 +436,13 @@ namespace Content.Server.Administration.Managers private static (bool isAvail, AdminFlags[] flagsReq) GetRequiredFlag(IConsoleCommand cmd) { - var type = cmd.GetType(); + MemberInfo type = cmd.GetType(); + + if (cmd is ConsoleHost.RegisteredCommand registered) + { + type = registered.Callback.Method; + } + if (Attribute.IsDefined(type, typeof(AnyCommandAttribute))) { // Available to everybody. diff --git a/Content.Server/Atmos/Commands/FixGridAtmos.cs b/Content.Server/Atmos/Commands/FixGridAtmos.cs deleted file mode 100644 index b0a6fee2ac..0000000000 --- a/Content.Server/Atmos/Commands/FixGridAtmos.cs +++ /dev/null @@ -1,103 +0,0 @@ -using Content.Server.Administration; -using Content.Server.Atmos.EntitySystems; -using Content.Server.Atmos.Components; -using Content.Shared.Administration; -using Content.Shared.Atmos; -using Content.Shared.Tag; -using Robust.Shared.Console; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Map; - -namespace Content.Server.Atmos.Commands -{ - [AdminCommand(AdminFlags.Debug)] - public class FixGridAtmos : IConsoleCommand - { - public string Command => "fixgridatmos"; - public string Description => "Makes every tile on a grid have a roundstart gas mix."; - public string Help => $"{Command} "; - public void Execute(IConsoleShell shell, string argStr, string[] args) - { - if (args.Length == 0) - { - shell.WriteError("Not enough arguments."); - return; - } - - var mapManager = IoCManager.Resolve(); - var entityManager = IoCManager.Resolve(); - var atmosphereSystem = EntitySystem.Get(); - - var mixtures = new GasMixture[6]; - for (var i = 0; i < mixtures.Length; i++) - mixtures[i] = new GasMixture(Atmospherics.CellVolume) { Temperature = Atmospherics.T20C }; - - // 0: Air - mixtures[0].AdjustMoles(Gas.Oxygen, Atmospherics.OxygenMolesStandard); - mixtures[0].AdjustMoles(Gas.Nitrogen, Atmospherics.NitrogenMolesStandard); - - // 1: Vaccum - - // 2: Oxygen (GM) - mixtures[2].AdjustMoles(Gas.Oxygen, Atmospherics.MolesCellGasMiner); - - // 3: Nitrogen (GM) - mixtures[3].AdjustMoles(Gas.Nitrogen, Atmospherics.MolesCellGasMiner); - - // 4: Plasma (GM) - mixtures[4].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner); - - // 5: Instant Plasmafire (r) - mixtures[5].AdjustMoles(Gas.Oxygen, Atmospherics.MolesCellGasMiner); - mixtures[5].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner); - mixtures[5].Temperature = 5000f; - - foreach (var gid in args) - { - // I like offering detailed error messages, that's why I don't use one of the extension methods. - if (!int.TryParse(gid, out var i) || i <= 0) - { - shell.WriteError($"Invalid grid ID \"{gid}\"."); - continue; - } - - var gridId = new GridId(i); - - if (!mapManager.TryGetGrid(gridId, out var mapGrid)) - { - shell.WriteError($"Grid \"{i}\" doesn't exist."); - continue; - } - - if (!entityManager.TryGetComponent(mapGrid.GridEntityId, out GridAtmosphereComponent? gridAtmosphere)) - { - shell.WriteError($"Grid \"{i}\" has no atmosphere component, try addatmos."); - continue; - } - - foreach (var (indices, tileMain) in gridAtmosphere.Tiles) - { - var tile = tileMain.Air; - if (tile == null) - continue; - - tile.Clear(); - var mixtureId = 0; - foreach (var entUid in mapGrid.GetAnchoredEntities(indices)) - { - if (!entityManager.TryGetComponent(entUid, out AtmosFixMarkerComponent? afm)) - continue; - mixtureId = afm.Mode; - break; - } - var mixture = mixtures[mixtureId]; - atmosphereSystem.Merge(tile, mixture); - tile.Temperature = mixture.Temperature; - - atmosphereSystem.InvalidateTile(gridAtmosphere, indices); - } - } - } - } -} diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Commands.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Commands.cs new file mode 100644 index 0000000000..9219aa3a1b --- /dev/null +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Commands.cs @@ -0,0 +1,107 @@ +using Content.Server.Administration; +using Content.Server.Atmos.Components; +using Content.Shared.Administration; +using Content.Shared.Atmos; +using Robust.Shared.Console; +using Robust.Shared.IoC; +using Robust.Shared.Map; + +namespace Content.Server.Atmos.EntitySystems; + +public partial class AtmosphereSystem +{ + [Dependency] private readonly IConsoleHost _consoleHost = default!; + + private void InitializeCommands() + { + // Fix Grid Atmos command. + _consoleHost.RegisterCommand("fixgridatmos", + "Makes every tile on a grid have a roundstart gas mix.", + "fixgridatmos ", FixGridAtmosCommand); + } + + private void ShutdownCommands() + { + _consoleHost.UnregisterCommand("fixgridatmos"); + } + + [AdminCommand(AdminFlags.Debug)] + private void FixGridAtmosCommand(IConsoleShell shell, string argstr, string[] args) + { + if (args.Length == 0) + { + shell.WriteError("Not enough arguments."); + return; + } + + var mixtures = new GasMixture[6]; + for (var i = 0; i < mixtures.Length; i++) + mixtures[i] = new GasMixture(Atmospherics.CellVolume) { Temperature = Atmospherics.T20C }; + + // 0: Air + mixtures[0].AdjustMoles(Gas.Oxygen, Atmospherics.OxygenMolesStandard); + mixtures[0].AdjustMoles(Gas.Nitrogen, Atmospherics.NitrogenMolesStandard); + + // 1: Vaccum + + // 2: Oxygen (GM) + mixtures[2].AdjustMoles(Gas.Oxygen, Atmospherics.MolesCellGasMiner); + + // 3: Nitrogen (GM) + mixtures[3].AdjustMoles(Gas.Nitrogen, Atmospherics.MolesCellGasMiner); + + // 4: Plasma (GM) + mixtures[4].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner); + + // 5: Instant Plasmafire (r) + mixtures[5].AdjustMoles(Gas.Oxygen, Atmospherics.MolesCellGasMiner); + mixtures[5].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner); + mixtures[5].Temperature = 5000f; + + foreach (var gid in args) + { + // I like offering detailed error messages, that's why I don't use one of the extension methods. + if (!int.TryParse(gid, out var i) || i <= 0) + { + shell.WriteError($"Invalid grid ID \"{gid}\"."); + continue; + } + + var gridId = new GridId(i); + + if (!_mapManager.TryGetGrid(gridId, out var mapGrid)) + { + shell.WriteError($"Grid \"{i}\" doesn't exist."); + continue; + } + + if (!TryComp(mapGrid.GridEntityId, out GridAtmosphereComponent? gridAtmosphere)) + { + shell.WriteError($"Grid \"{i}\" has no atmosphere component, try addatmos."); + continue; + } + + foreach (var (indices, tileMain) in gridAtmosphere.Tiles) + { + var tile = tileMain.Air; + if (tile == null) + continue; + + tile.Clear(); + var mixtureId = 0; + foreach (var entUid in mapGrid.GetAnchoredEntities(indices)) + { + if (!TryComp(entUid, out AtmosFixMarkerComponent? afm)) + continue; + mixtureId = afm.Mode; + break; + } + var mixture = mixtures[mixtureId]; + Merge(tile, mixture); + tile.Temperature = mixture.Temperature; + + InvalidateTile(gridAtmosphere, indices); + } + } + } +} diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs index ad497a64ec..0231049cde 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs @@ -1,11 +1,15 @@ +using Content.Server.Administration; using Content.Server.Administration.Logs; using Content.Server.Atmos.Components; +using Content.Server.Database; using Content.Server.NodeContainer.EntitySystems; using Content.Server.Temperature.Components; using Content.Server.Temperature.Systems; +using Content.Shared.Administration; using Content.Shared.Atmos.EntitySystems; using Content.Shared.Maps; using JetBrains.Annotations; +using Robust.Shared.Console; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; @@ -31,6 +35,7 @@ namespace Content.Server.Atmos.EntitySystems UpdatesAfter.Add(typeof(NodeGroupSystem)); InitializeGases(); + InitializeCommands(); InitializeCVars(); InitializeGrid(); @@ -47,6 +52,8 @@ namespace Content.Server.Atmos.EntitySystems base.Shutdown(); _mapManager.TileChanged -= OnTileChanged; + + ShutdownCommands(); } private void OnTileChanged(object? sender, TileChangedEventArgs eventArgs) diff --git a/Content.Shared/Administration/AnyCommandAttribute.cs b/Content.Shared/Administration/AnyCommandAttribute.cs index 426389b4e3..a98ec7da95 100644 --- a/Content.Shared/Administration/AnyCommandAttribute.cs +++ b/Content.Shared/Administration/AnyCommandAttribute.cs @@ -7,7 +7,7 @@ namespace Content.Shared.Administration /// /// Specifies that a command can be executed by any player. /// - [AttributeUsage(AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] [BaseTypeRequired(typeof(IConsoleCommand))] [MeansImplicitUse] public sealed class AnyCommandAttribute : Attribute