Reorganize commands into the Commands folder (#2679)

* Reorganize commands into the Commands folder

* RIDER
This commit is contained in:
DrSmugleaf
2020-12-03 03:40:47 +01:00
committed by GitHub
parent 7905d93564
commit 87f9a6e167
69 changed files with 2817 additions and 2293 deletions

View File

@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Content.Server.Commands.GameTicking;
using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking;
using Content.Shared;

View File

@@ -1,635 +0,0 @@
#nullable enable
using System;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Atmos;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.GameObjects.EntitySystems.Atmos;
using Content.Shared.Administration;
using Content.Shared.Atmos;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Content.Server.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class AddAtmos : IClientCommand
{
public string Command => "addatmos";
public string Description => "Adds atmos support to a grid.";
public string Help => $"{Command} <GridId>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (grid.HasComponent<IGridAtmosphereComponent>())
{
shell.SendText(player, "Grid already has an atmosphere.");
return;
}
grid.AddComponent<GridAtmosphereComponent>();
shell.SendText(player, $"Added atmosphere to grid {id}.");
}
}
[AdminCommand(AdminFlags.Debug)]
public class AddUnsimulatedAtmos : IClientCommand
{
public string Command => "addunsimulatedatmos";
public string Description => "Adds unimulated atmos support to a grid.";
public string Help => $"{Command} <GridId>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (grid.HasComponent<IGridAtmosphereComponent>())
{
shell.SendText(player, "Grid already has an atmosphere.");
return;
}
grid.AddComponent<UnsimulatedGridAtmosphereComponent>();
shell.SendText(player, $"Added unsimulated atmosphere to grid {id}.");
}
}
[AdminCommand(AdminFlags.Debug)]
public class ListGases : IClientCommand
{
public string Command => "listgases";
public string Description => "Prints a list of gases and their indices.";
public string Help => "listgases";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
var atmosSystem = EntitySystem.Get<AtmosphereSystem>();
foreach (var gasPrototype in atmosSystem.Gases)
{
shell.SendText(player, $"{gasPrototype.Name} ID: {gasPrototype.ID}");
}
}
}
[AdminCommand(AdminFlags.Debug)]
public class AddGas : IClientCommand
{
public string Command => "addgas";
public string Description => "Adds gas at a certain position.";
public string Help => "addgas <X> <Y> <GridId> <Gas> <moles>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 5) return;
if(!int.TryParse(args[0], out var x)
|| !int.TryParse(args[1], out var y)
|| !int.TryParse(args[2], out var id)
|| !(AtmosCommandUtils.TryParseGasID(args[3], out var gasId))
|| !float.TryParse(args[4], out var moles)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var indices = new Vector2i(x, y);
var tile = gam.GetTile(indices);
if (tile == null)
{
shell.SendText(player, "Invalid coordinates.");
return;
}
if (tile.Air == null)
{
shell.SendText(player, "Can't add gas to that tile.");
return;
}
tile.Air.AdjustMoles(gasId, moles);
gam.Invalidate(indices);
}
}
[AdminCommand(AdminFlags.Debug)]
public class FillGas : IClientCommand
{
public string Command => "fillgas";
public string Description => "Adds gas to all tiles in a grid.";
public string Help => "fillgas <GridId> <Gas> <moles>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 3) return;
if(!int.TryParse(args[0], out var id)
|| !(AtmosCommandUtils.TryParseGasID(args[1], out var gasId))
|| !float.TryParse(args[2], out var moles)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
foreach (var tile in gam)
{
tile.Air?.AdjustMoles(gasId, moles);
gam.Invalidate(tile.GridIndices);
}
}
}
[AdminCommand(AdminFlags.Debug)]
public class RemoveGas : IClientCommand
{
public string Command => "removegas";
public string Description => "Removes an amount of gases.";
public string Help => "removegas <X> <Y> <GridId> <amount> <ratio>\nIf <ratio> is true, amount will be treated as the ratio of gas to be removed.";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 5) return;
if(!int.TryParse(args[0], out var x)
|| !int.TryParse(args[1], out var y)
|| !int.TryParse(args[2], out var id)
|| !float.TryParse(args[3], out var amount)
|| !bool.TryParse(args[4], out var ratio)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var indices = new Vector2i(x, y);
var tile = gam.GetTile(indices);
if (tile == null)
{
shell.SendText(player, "Invalid coordinates.");
return;
}
if (tile.Air == null)
{
shell.SendText(player, "Can't remove gas from that tile.");
return;
}
if (ratio)
tile.Air.RemoveRatio(amount);
else
tile.Air.Remove(amount);
gam.Invalidate(indices);
}
}
[AdminCommand(AdminFlags.Debug)]
public class SetTemperature : IClientCommand
{
public string Command => "settemp";
public string Description => "Sets a tile's temperature (in kelvin).";
public string Help => "Usage: settemp <X> <Y> <GridId> <Temperature>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 4) return;
if(!int.TryParse(args[0], out var x)
|| !int.TryParse(args[1], out var y)
|| !int.TryParse(args[2], out var id)
|| !float.TryParse(args[3], out var temperature)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (temperature < Atmospherics.TCMB)
{
shell.SendText(player, "Invalid temperature.");
return;
}
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var indices = new Vector2i(x, y);
var tile = gam.GetTile(indices);
if (tile == null)
{
shell.SendText(player, "Invalid coordinates.");
return;
}
if (tile.Air == null)
{
shell.SendText(player, "Can't change that tile's temperature.");
return;
}
tile.Air.Temperature = temperature;
gam.Invalidate(indices);
}
}
[AdminCommand(AdminFlags.Debug)]
public class SetAtmosTemperature : IClientCommand
{
public string Command => "setatmostemp";
public string Description => "Sets a grid's temperature (in kelvin).";
public string Help => "Usage: setatmostemp <GridId> <Temperature>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 2) return;
if(!int.TryParse(args[0], out var id)
|| !float.TryParse(args[1], out var temperature)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (temperature < Atmospherics.TCMB)
{
shell.SendText(player, "Invalid temperature.");
return;
}
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var tiles = 0;
foreach (var tile in gam)
{
if (tile.Air == null)
continue;
tiles++;
tile.Air.Temperature = temperature;
gam.Invalidate(tile.GridIndices);
}
shell.SendText(player, $"Changed the temperature of {tiles} tiles.");
}
}
[AdminCommand(AdminFlags.Debug)]
public class DeleteGasCommand : IClientCommand
{
public string Command => "deletegas";
public string Description => "Removes all gases from a grid, or just of one type if specified.";
public string Help => $"Usage: {Command} <GridId> <Gas> / {Command} <GridId> / {Command} <Gas> / {Command}";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
GridId gridId;
Gas? gas = null;
switch (args.Length)
{
case 0:
if (player == null)
{
shell.SendText(player, "A grid must be specified when the command isn't used by a player.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity to get a grid from.");
return;
}
gridId = player.AttachedEntity.Transform.GridID;
if (gridId == GridId.Invalid)
{
shell.SendText(player, "You aren't on a grid to delete gas from.");
return;
}
break;
case 1:
{
if (!int.TryParse(args[0], out var number))
{
// Argument is a gas
if (player == null)
{
shell.SendText(player, "A grid id must be specified if not using this command as a player.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity from which to get a grid id.");
return;
}
gridId = player.AttachedEntity.Transform.GridID;
if (gridId == GridId.Invalid)
{
shell.SendText(player, "You aren't on a grid to delete gas from.");
return;
}
if (!Enum.TryParse<Gas>(args[0], true, out var parsedGas))
{
shell.SendText(player, $"{args[0]} is not a valid gas name.");
return;
}
gas = parsedGas;
break;
}
// Argument is a grid
gridId = new GridId(number);
if (gridId == GridId.Invalid)
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
break;
}
case 2:
{
if (!int.TryParse(args[0], out var first))
{
shell.SendText(player, $"{args[0]} is not a valid integer for a grid id.");
return;
}
gridId = new GridId(first);
if (gridId == GridId.Invalid)
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
if (!Enum.TryParse<Gas>(args[1], true, out var parsedGas))
{
shell.SendText(player, $"{args[1]} is not a valid gas.");
return;
}
gas = parsedGas;
break;
}
default:
shell.SendText(player, Help);
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
if (!mapManager.TryGetGrid(gridId, out var grid))
{
shell.SendText(player, $"No grid exists with id {gridId}");
return;
}
var entityManager = IoCManager.Resolve<IEntityManager>();
if (!entityManager.TryGetEntity(grid.GridEntityId, out var gridEntity))
{
shell.SendText(player, $"Grid {gridId} has no entity.");
return;
}
if (!gridEntity.TryGetComponent(out GridAtmosphereComponent? atmosphere))
{
shell.SendText(player, $"Grid {gridId} has no {nameof(GridAtmosphereComponent)}");
return;
}
var tiles = 0;
var moles = 0f;
if (gas == null)
{
foreach (var tile in atmosphere)
{
if (tile.Air == null || tile.Air.Immutable) continue;
tiles++;
moles += tile.Air.TotalMoles;
tile.Air.Clear();
atmosphere.Invalidate(tile.GridIndices);
}
}
else
{
foreach (var tile in atmosphere)
{
if (tile.Air == null || tile.Air.Immutable) continue;
tiles++;
moles += tile.Air.TotalMoles;
tile.Air.SetMoles(gas.Value, 0);
atmosphere.Invalidate(tile.GridIndices);
}
}
if (gas == null)
{
shell.SendText(player, $"Removed {moles} moles from {tiles} tiles.");
return;
}
shell.SendText(player, $"Removed {moles} moles of gas {gas} from {tiles} tiles.");
}
}
[AdminCommand(AdminFlags.Debug)]
public class ShowAtmos : IClientCommand
{
public string Command => "showatmos";
public string Description => "Toggles seeing atmos debug overlay.";
public string Help => $"Usage: {Command}";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "You must be a player to use this command.");
return;
}
var atmosDebug = EntitySystem.Get<AtmosDebugOverlaySystem>();
var enabled = atmosDebug.ToggleObserver(player);
shell.SendText(player, enabled
? "Enabled the atmospherics debug overlay."
: "Disabled the atmospherics debug overlay.");
}
}
}

View File

@@ -0,0 +1,59 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Movement;
using Content.Server.GameObjects.EntitySystems.AI;
using Content.Shared.Administration;
using Content.Shared.GameObjects.Components.Movement;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.Commands.AI
{
[AdminCommand(AdminFlags.Fun)]
public class AddAiCommand : IClientCommand
{
public string Command => "addai";
public string Description => "Add an ai component with a given processor to an entity.";
public string Help => "Usage: addai <processorId> <entityId>"
+ "\n processorId: Class that inherits AiLogicProcessor and has an AiLogicProcessor attribute."
+ "\n entityID: Uid of entity to add the AiControllerComponent to. Open its VV menu to find this.";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if(args.Length != 2)
{
shell.SendText(player, "Wrong number of args.");
return;
}
var processorId = args[0];
var entId = new EntityUid(int.Parse(args[1]));
var ent = IoCManager.Resolve<IEntityManager>().GetEntity(entId);
var aiSystem = EntitySystem.Get<AiSystem>();
if (!aiSystem.ProcessorTypeExists(processorId))
{
shell.SendText(player, "Invalid processor type. Processor must inherit AiLogicProcessor and have an AiLogicProcessor attribute.");
return;
}
if (ent.HasComponent<AiControllerComponent>())
{
shell.SendText(player, "Entity already has an AI component.");
return;
}
if (ent.HasComponent<IMoverComponent>())
{
ent.RemoveComponent<IMoverComponent>();
}
var comp = ent.AddComponent<AiControllerComponent>();
comp.LogicName = processorId;
shell.SendText(player, "AI component added.");
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Text;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.AI;
using Content.Server.GameObjects.EntitySystems.AI;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Localization;
namespace Content.Server.Commands.AI
{
[AdminCommand(AdminFlags.Fun)]
public sealed class FactionCommand : IClientCommand
{
public string Command => "factions";
public string Description => "Update / list factional relationships for NPCs.";
public string Help => "faction <source> <friendly/hostile> target\n" +
"faction <source> list: hostile factions";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length == 0)
{
var result = new StringBuilder();
foreach (Faction value in Enum.GetValues(typeof(Faction)))
{
if (value == Faction.None)
continue;
result.Append(value + "\n");
}
shell.SendText(player, result.ToString());
return;
}
if (args.Length < 2)
{
shell.SendText(player, Loc.GetString("Need more args"));
return;
}
if (!Enum.TryParse(args[0], true, out Faction faction))
{
shell.SendText(player, Loc.GetString("Invalid faction"));
return;
}
Faction targetFaction;
switch (args[1])
{
case "friendly":
if (args.Length < 3)
{
shell.SendText(player, Loc.GetString("Need to supply a target faction"));
return;
}
if (!Enum.TryParse(args[2], true, out targetFaction))
{
shell.SendText(player, Loc.GetString("Invalid target faction"));
return;
}
EntitySystem.Get<AiFactionTagSystem>().MakeFriendly(faction, targetFaction);
shell.SendText(player, Loc.GetString("Command successful"));
break;
case "hostile":
if (args.Length < 3)
{
shell.SendText(player, Loc.GetString("Need to supply a target faction"));
return;
}
if (!Enum.TryParse(args[2], true, out targetFaction))
{
shell.SendText(player, Loc.GetString("Invalid target faction"));
return;
}
EntitySystem.Get<AiFactionTagSystem>().MakeHostile(faction, targetFaction);
shell.SendText(player, Loc.GetString("Command successful"));
break;
case "list":
shell.SendText(player, EntitySystem.Get<AiFactionTagSystem>().GetHostileFactions(faction).ToString());
break;
default:
shell.SendText(player, Loc.GetString("Unknown faction arg"));
break;
}
return;
}
}
}

View File

@@ -0,0 +1,55 @@
#nullable enable
using System;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs;
using Content.Shared.Administration;
using Content.Shared.Alert;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Alerts
{
[AdminCommand(AdminFlags.Debug)]
public sealed class ClearAlert : IClientCommand
{
public string Command => "clearalert";
public string Description => "Clears an alert for a player, defaulting to current player";
public string Help => "clearalert <alertType> <name or userID, omit for current player>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
var attachedEntity = player?.AttachedEntity;
if (attachedEntity == null)
{
shell.SendText(player, "You don't have an entity.");
return;
}
if (args.Length > 1)
{
var target = args[1];
if (!CommandUtils.TryGetAttachedEntityByUsernameOrId(shell, target, player, out attachedEntity)) return;
}
if (!CommandUtils.ValidateAttachedEntity(shell, player, attachedEntity)) return;
if (!attachedEntity.TryGetComponent(out ServerAlertsComponent? alertsComponent))
{
shell.SendText(player, "user has no alerts component");
return;
}
var alertType = args[0];
var alertMgr = IoCManager.Resolve<AlertManager>();
if (!alertMgr.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
{
shell.SendText(player, "unrecognized alertType " + alertType);
return;
}
alertsComponent.ClearAlert(alert.AlertType);
}
}
}

View File

@@ -0,0 +1,67 @@
#nullable enable
using System;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs;
using Content.Shared.Administration;
using Content.Shared.Alert;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Alerts
{
[AdminCommand(AdminFlags.Debug)]
public sealed class ShowAlert : IClientCommand
{
public string Command => "showalert";
public string Description => "Shows an alert for a player, defaulting to current player";
public string Help => "showalert <alertType> <severity, -1 if no severity> <name or userID, omit for current player>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "You cannot run this command from the server.");
return;
}
var attachedEntity = player.AttachedEntity;
if (attachedEntity == null)
{
shell.SendText(player, "You don't have an entity.");
return;
}
if (args.Length > 2)
{
var target = args[2];
if (!CommandUtils.TryGetAttachedEntityByUsernameOrId(shell, target, player, out attachedEntity)) return;
}
if (!CommandUtils.ValidateAttachedEntity(shell, player, attachedEntity))
return;
if (!attachedEntity.TryGetComponent(out ServerAlertsComponent? alertsComponent))
{
shell.SendText(player, "user has no alerts component");
return;
}
var alertType = args[0];
var severity = args[1];
var alertMgr = IoCManager.Resolve<AlertManager>();
if (!alertMgr.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
{
shell.SendText(player, "unrecognized alertType " + alertType);
return;
}
if (!short.TryParse(severity, out var sevint))
{
shell.SendText(player, "invalid severity " + sevint);
return;
}
alertsComponent.ShowAlert(alert.AlertType, sevint == -1 ? (short?) null : sevint);
}
}
}

View File

@@ -0,0 +1,65 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.Atmos;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class AddAtmosCommand : IClientCommand
{
public string Command => "addatmos";
public string Description => "Adds atmos support to a grid.";
public string Help => $"{Command} <GridId>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (grid.HasComponent<IGridAtmosphereComponent>())
{
shell.SendText(player, "Grid already has an atmosphere.");
return;
}
grid.AddComponent<GridAtmosphereComponent>();
shell.SendText(player, $"Added atmosphere to grid {id}.");
}
}
}

View File

@@ -0,0 +1,76 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Content.Shared.Atmos;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class AddGasCommand : IClientCommand
{
public string Command => "addgas";
public string Description => "Adds gas at a certain position.";
public string Help => "addgas <X> <Y> <GridId> <Gas> <moles>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 5) return;
if(!int.TryParse(args[0], out var x)
|| !int.TryParse(args[1], out var y)
|| !int.TryParse(args[2], out var id)
|| !(AtmosCommandUtils.TryParseGasID(args[3], out var gasId))
|| !float.TryParse(args[4], out var moles)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var indices = new Vector2i(x, y);
var tile = gam.GetTile(indices);
if (tile == null)
{
shell.SendText(player, "Invalid coordinates.");
return;
}
if (tile.Air == null)
{
shell.SendText(player, "Can't add gas to that tile.");
return;
}
tile.Air.AdjustMoles(gasId, moles);
gam.Invalidate(indices);
}
}
}

View File

@@ -0,0 +1,66 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.Atmos;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class AddUnsimulatedAtmosCommand : IClientCommand
{
public string Command => "addunsimulatedatmos";
public string Description => "Adds unimulated atmos support to a grid.";
public string Help => $"{Command} <GridId>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (grid.HasComponent<IGridAtmosphereComponent>())
{
shell.SendText(player, "Grid already has an atmosphere.");
return;
}
grid.AddComponent<UnsimulatedGridAtmosphereComponent>();
shell.SendText(player, $"Added unsimulated atmosphere to grid {id}.");
}
}
}

View File

@@ -0,0 +1,193 @@
#nullable enable
using System;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Content.Shared.Atmos;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class DeleteGasCommand : IClientCommand
{
public string Command => "deletegas";
public string Description => "Removes all gases from a grid, or just of one type if specified.";
public string Help => $"Usage: {Command} <GridId> <Gas> / {Command} <GridId> / {Command} <Gas> / {Command}";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
GridId gridId;
Gas? gas = null;
switch (args.Length)
{
case 0:
if (player == null)
{
shell.SendText(player, "A grid must be specified when the command isn't used by a player.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity to get a grid from.");
return;
}
gridId = player.AttachedEntity.Transform.GridID;
if (gridId == GridId.Invalid)
{
shell.SendText(player, "You aren't on a grid to delete gas from.");
return;
}
break;
case 1:
{
if (!int.TryParse(args[0], out var number))
{
// Argument is a gas
if (player == null)
{
shell.SendText(player, "A grid id must be specified if not using this command as a player.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity from which to get a grid id.");
return;
}
gridId = player.AttachedEntity.Transform.GridID;
if (gridId == GridId.Invalid)
{
shell.SendText(player, "You aren't on a grid to delete gas from.");
return;
}
if (!Enum.TryParse<Gas>(args[0], true, out var parsedGas))
{
shell.SendText(player, $"{args[0]} is not a valid gas name.");
return;
}
gas = parsedGas;
break;
}
// Argument is a grid
gridId = new GridId(number);
if (gridId == GridId.Invalid)
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
break;
}
case 2:
{
if (!int.TryParse(args[0], out var first))
{
shell.SendText(player, $"{args[0]} is not a valid integer for a grid id.");
return;
}
gridId = new GridId(first);
if (gridId == GridId.Invalid)
{
shell.SendText(player, $"{gridId} is not a valid grid id.");
return;
}
if (!Enum.TryParse<Gas>(args[1], true, out var parsedGas))
{
shell.SendText(player, $"{args[1]} is not a valid gas.");
return;
}
gas = parsedGas;
break;
}
default:
shell.SendText(player, Help);
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
if (!mapManager.TryGetGrid(gridId, out var grid))
{
shell.SendText(player, $"No grid exists with id {gridId}");
return;
}
var entityManager = IoCManager.Resolve<IEntityManager>();
if (!entityManager.TryGetEntity(grid.GridEntityId, out var gridEntity))
{
shell.SendText(player, $"Grid {gridId} has no entity.");
return;
}
if (!gridEntity.TryGetComponent(out GridAtmosphereComponent? atmosphere))
{
shell.SendText(player, $"Grid {gridId} has no {nameof(GridAtmosphereComponent)}");
return;
}
var tiles = 0;
var moles = 0f;
if (gas == null)
{
foreach (var tile in atmosphere)
{
if (tile.Air == null || tile.Air.Immutable) continue;
tiles++;
moles += tile.Air.TotalMoles;
tile.Air.Clear();
atmosphere.Invalidate(tile.GridIndices);
}
}
else
{
foreach (var tile in atmosphere)
{
if (tile.Air == null || tile.Air.Immutable) continue;
tiles++;
moles += tile.Air.TotalMoles;
tile.Air.SetMoles(gas.Value, 0);
atmosphere.Invalidate(tile.GridIndices);
}
}
if (gas == null)
{
shell.SendText(player, $"Removed {moles} moles from {tiles} tiles.");
return;
}
shell.SendText(player, $"Removed {moles} moles of gas {gas} from {tiles} tiles.");
}
}
}

View File

@@ -0,0 +1,63 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Content.Shared.Atmos;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class FillGas : IClientCommand
{
public string Command => "fillgas";
public string Description => "Adds gas to all tiles in a grid.";
public string Help => "fillgas <GridId> <Gas> <moles>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 3) return;
if(!int.TryParse(args[0], out var id)
|| !(AtmosCommandUtils.TryParseGasID(args[1], out var gasId))
|| !float.TryParse(args[2], out var moles)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
foreach (var tile in gam)
{
tile.Air?.AdjustMoles(gasId, moles);
gam.Invalidate(tile.GridIndices);
}
}
}
}

View File

@@ -0,0 +1,29 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Systems;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class ListGasesCommand : IClientCommand
{
public string Command => "listgases";
public string Description => "Prints a list of gases and their indices.";
public string Help => "listgases";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
var atmosSystem = EntitySystem.Get<AtmosphereSystem>();
foreach (var gasPrototype in atmosSystem.Gases)
{
shell.SendText(player, $"{gasPrototype.Name} ID: {gasPrototype.ID}");
}
}
}
}

View File

@@ -0,0 +1,80 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class RemoveGasCommand : IClientCommand
{
public string Command => "removegas";
public string Description => "Removes an amount of gases.";
public string Help => "removegas <X> <Y> <GridId> <amount> <ratio>\nIf <ratio> is true, amount will be treated as the ratio of gas to be removed.";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 5) return;
if(!int.TryParse(args[0], out var x)
|| !int.TryParse(args[1], out var y)
|| !int.TryParse(args[2], out var id)
|| !float.TryParse(args[3], out var amount)
|| !bool.TryParse(args[4], out var ratio)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var indices = new Vector2i(x, y);
var tile = gam.GetTile(indices);
if (tile == null)
{
shell.SendText(player, "Invalid coordinates.");
return;
}
if (tile.Air == null)
{
shell.SendText(player, "Can't remove gas from that tile.");
return;
}
if (ratio)
tile.Air.RemoveRatio(amount);
else
tile.Air.Remove(amount);
gam.Invalidate(indices);
}
}
}

View File

@@ -0,0 +1,75 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Content.Shared.Atmos;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class SetAtmosTemperatureCommand : IClientCommand
{
public string Command => "setatmostemp";
public string Description => "Sets a grid's temperature (in kelvin).";
public string Help => "Usage: setatmostemp <GridId> <Temperature>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 2) return;
if(!int.TryParse(args[0], out var id)
|| !float.TryParse(args[1], out var temperature)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (temperature < Atmospherics.TCMB)
{
shell.SendText(player, "Invalid temperature.");
return;
}
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var tiles = 0;
foreach (var tile in gam)
{
if (tile.Air == null)
continue;
tiles++;
tile.Air.Temperature = temperature;
gam.Invalidate(tile.GridIndices);
}
shell.SendText(player, $"Changed the temperature of {tiles} tiles.");
}
}
}

View File

@@ -0,0 +1,81 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Atmos;
using Content.Shared.Administration;
using Content.Shared.Atmos;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class SetTemperatureCommand : IClientCommand
{
public string Command => "settemp";
public string Description => "Sets a tile's temperature (in kelvin).";
public string Help => "Usage: settemp <X> <Y> <GridId> <Temperature>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 4) return;
if(!int.TryParse(args[0], out var x)
|| !int.TryParse(args[1], out var y)
|| !int.TryParse(args[2], out var id)
|| !float.TryParse(args[3], out var temperature)) return;
var gridId = new GridId(id);
var mapMan = IoCManager.Resolve<IMapManager>();
if (temperature < Atmospherics.TCMB)
{
shell.SendText(player, "Invalid temperature.");
return;
}
if (!gridId.IsValid() || !mapMan.TryGetGrid(gridId, out var gridComp))
{
shell.SendText(player, "Invalid grid ID.");
return;
}
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetEntity(gridComp.GridEntityId, out var grid))
{
shell.SendText(player, "Failed to get grid entity.");
return;
}
if (!grid.HasComponent<GridAtmosphereComponent>())
{
shell.SendText(player, "Grid doesn't have an atmosphere.");
return;
}
var gam = grid.GetComponent<GridAtmosphereComponent>();
var indices = new Vector2i(x, y);
var tile = gam.GetTile(indices);
if (tile == null)
{
shell.SendText(player, "Invalid coordinates.");
return;
}
if (tile.Air == null)
{
shell.SendText(player, "Can't change that tile's temperature.");
return;
}
tile.Air.Temperature = temperature;
gam.Invalidate(indices);
}
}
}

View File

@@ -0,0 +1,34 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.EntitySystems.Atmos;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Systems;
namespace Content.Server.Commands.Atmos
{
[AdminCommand(AdminFlags.Debug)]
public class ShowAtmos : IClientCommand
{
public string Command => "showatmos";
public string Description => "Toggles seeing atmos debug overlay.";
public string Help => $"Usage: {Command}";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "You must be a player to use this command.");
return;
}
var atmosDebug = EntitySystem.Get<AtmosDebugOverlaySystem>();
var enabled = atmosDebug.ToggleObserver(player);
shell.SendText(player, enabled
? "Enabled the atmospherics debug overlay."
: "Disabled the atmospherics debug overlay.");
}
}
}

View File

@@ -1,13 +1,8 @@
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Body;
using Content.Shared.GameObjects.Components.Body.Part;
using Content.Shared.GameObjects.Components.Damage;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
@@ -17,7 +12,7 @@ using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
namespace Content.Server.GameObjects.Components.Body
namespace Content.Server.Commands.Body
{
[AdminCommand(AdminFlags.Fun)]
class AddHandCommand : IClientCommand
@@ -152,99 +147,4 @@ namespace Content.Server.GameObjects.Components.Body
shell.SendText(player, response);
}
}
[AdminCommand(AdminFlags.Fun)]
class RemoveHandCommand : IClientCommand
{
public string Command => "removehand";
public string Description => "Removes a hand from your entity.";
public string Help => $"Usage: {Command}";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "Only a player can run this command.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity.");
return;
}
if (!player.AttachedEntity.TryGetComponent(out IBody? body))
{
var random = IoCManager.Resolve<IRobustRandom>();
var text = $"You have no body{(random.Prob(0.2f) ? " and you must scream." : ".")}";
shell.SendText(player, text);
return;
}
var hand = body.Parts.FirstOrDefault(x => x.Value.PartType == BodyPartType.Hand);
if (hand.Value.Equals(default))
{
shell.SendText(player, "You have no hands.");
}
else
{
body.RemovePart(hand.Value);
}
}
}
[AdminCommand(AdminFlags.Fun)]
class DestroyMechanismCommand : IClientCommand
{
public string Command => "destroymechanism";
public string Description => "Destroys a mechanism from your entity";
public string Help => $"Usage: {Command} <mechanism>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "Only a player can run this command.");
return;
}
if (args.Length == 0)
{
shell.SendText(player, Help);
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity.");
return;
}
if (!player.AttachedEntity.TryGetComponent(out IBody? body))
{
var random = IoCManager.Resolve<IRobustRandom>();
var text = $"You have no body{(random.Prob(0.2f) ? " and you must scream." : ".")}";
shell.SendText(player, text);
return;
}
var mechanismName = string.Join(" ", args).ToLowerInvariant();
foreach (var part in body.Parts.Values)
foreach (var mechanism in part.Mechanisms)
{
if (mechanism.Name.ToLowerInvariant() == mechanismName)
{
part.DeleteMechanism(mechanism);
shell.SendText(player, $"Mechanism with name {mechanismName} has been destroyed.");
return;
}
}
shell.SendText(player, $"No mechanism was found with name {mechanismName}.");
}
}
}

View File

@@ -0,0 +1,65 @@
#nullable enable
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.GameObjects.Components.Body;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Random;
namespace Content.Server.Commands.Body
{
[AdminCommand(AdminFlags.Fun)]
class DestroyMechanismCommand : IClientCommand
{
public string Command => "destroymechanism";
public string Description => "Destroys a mechanism from your entity";
public string Help => $"Usage: {Command} <mechanism>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "Only a player can run this command.");
return;
}
if (args.Length == 0)
{
shell.SendText(player, Help);
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity.");
return;
}
if (!player.AttachedEntity.TryGetComponent(out IBody? body))
{
var random = IoCManager.Resolve<IRobustRandom>();
var text = $"You have no body{(random.Prob(0.2f) ? " and you must scream." : ".")}";
shell.SendText(player, text);
return;
}
var mechanismName = string.Join(" ", args).ToLowerInvariant();
foreach (var part in body.Parts.Values)
foreach (var mechanism in part.Mechanisms)
{
if (mechanism.Name.ToLowerInvariant() == mechanismName)
{
part.DeleteMechanism(mechanism);
shell.SendText(player, $"Mechanism with name {mechanismName} has been destroyed.");
return;
}
}
shell.SendText(player, $"No mechanism was found with name {mechanismName}.");
}
}
}

View File

@@ -0,0 +1,56 @@
#nullable enable
using System.Linq;
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.GameObjects.Components.Body;
using Content.Shared.GameObjects.Components.Body.Part;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Random;
namespace Content.Server.Commands.Body
{
[AdminCommand(AdminFlags.Fun)]
class RemoveHandCommand : IClientCommand
{
public string Command => "removehand";
public string Description => "Removes a hand from your entity.";
public string Help => $"Usage: {Command}";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "Only a player can run this command.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You have no entity.");
return;
}
if (!player.AttachedEntity.TryGetComponent(out IBody? body))
{
var random = IoCManager.Resolve<IRobustRandom>();
var text = $"You have no body{(random.Prob(0.2f) ? " and you must scream." : ".")}";
shell.SendText(player, text);
return;
}
var hand = body.Parts.FirstOrDefault(x => x.Value.PartType == BodyPartType.Hand);
if (hand.Value.Equals(default))
{
shell.SendText(player, "You have no hands.");
}
else
{
body.RemovePart(hand.Value);
}
}
}
}

View File

@@ -0,0 +1,31 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.Interfaces.Chat;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Chat
{
[AdminCommand(AdminFlags.Admin)]
internal class AdminChatCommand : IClientCommand
{
public string Command => "asay";
public string Description => "Send chat messages to the private admin chat channel.";
public string Help => "asay <text>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 1)
return;
var message = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(message))
return;
var chat = IoCManager.Resolve<IChatManager>();
chat.SendAdminChat(player, message);
}
}
}

View File

@@ -0,0 +1,49 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.Interfaces.Chat;
using Content.Server.Players;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Enums;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Chat
{
[AnyCommand]
internal class MeCommand : IClientCommand
{
public string Command => "me";
public string Description => "Perform an action.";
public string Help => "me <text>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "This command cannot be run from the server.");
return;
}
if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue)
return;
if (args.Length < 1)
return;
var action = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(action))
return;
var chat = IoCManager.Resolve<IChatManager>();
var mindComponent = player.ContentData()?.Mind;
if (mindComponent == null)
{
shell.SendText(player, "You don't have a mind!");
return;
}
chat.EntityMe(mindComponent.OwnedEntity, action);
}
}
}

View File

@@ -0,0 +1,30 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.Interfaces.Chat;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Chat
{
[AnyCommand]
internal class OOCCommand : IClientCommand
{
public string Command => "ooc";
public string Description => "Send Out Of Character chat messages.";
public string Help => "ooc <text>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length < 1)
return;
var message = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(message))
return;
var chat = IoCManager.Resolve<IChatManager>();
chat.SendOOC(player, message);
}
}
}

View File

@@ -0,0 +1,64 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.Interfaces.Chat;
using Content.Server.Players;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Enums;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Chat
{
[AnyCommand]
internal class SayCommand : IClientCommand
{
public string Command => "say";
public string Description => "Send chat messages to the local channel or a specified radio channel.";
public string Help => "say <text>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "This command cannot be run from the server.");
return;
}
if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue)
return;
if (args.Length < 1)
return;
var message = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(message))
return;
var chat = IoCManager.Resolve<IChatManager>();
var playerEntity = player.AttachedEntity;
if (playerEntity == null)
{
shell.SendText(player, "You don't have an entity!");
return;
}
if (playerEntity.HasComponent<GhostComponent>())
chat.SendDeadChat(player, message);
else
{
var mindComponent = player.ContentData()?.Mind;
if (mindComponent == null)
{
shell.SendText(player, "You don't have a mind!");
return;
}
chat.EntitySay(mindComponent.OwnedEntity, message);
}
}
}
}

View File

@@ -1,15 +1,14 @@
using System;
#nullable enable
using System;
using System.Linq;
using Content.Server.Administration;
using Content.Server.Commands.Observer;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.Interfaces.Chat;
using Content.Server.Interfaces.GameObjects;
using Content.Server.Observer;
using Content.Server.Players;
using Content.Server.Utility;
using Content.Shared.Administration;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.Interfaces;
@@ -20,108 +19,8 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
namespace Content.Server.Chat
namespace Content.Server.Commands.Chat
{
[AnyCommand]
internal class SayCommand : IClientCommand
{
public string Command => "say";
public string Description => "Send chat messages to the local channel or a specified radio channel.";
public string Help => "say <text>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue)
return;
if (args.Length < 1)
return;
var message = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(message))
return;
var chat = IoCManager.Resolve<IChatManager>();
if (player.AttachedEntity.HasComponent<GhostComponent>())
chat.SendDeadChat(player, message);
else
{
var mindComponent = player.ContentData().Mind;
chat.EntitySay(mindComponent.OwnedEntity, message);
}
}
}
[AnyCommand]
internal class MeCommand : IClientCommand
{
public string Command => "me";
public string Description => "Perform an action.";
public string Help => "me <text>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player.Status != SessionStatus.InGame || !player.AttachedEntityUid.HasValue)
return;
if (args.Length < 1)
return;
var action = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(action))
return;
var chat = IoCManager.Resolve<IChatManager>();
var mindComponent = player.ContentData().Mind;
chat.EntityMe(mindComponent.OwnedEntity, action);
}
}
[AnyCommand]
internal class OOCCommand : IClientCommand
{
public string Command => "ooc";
public string Description => "Send Out Of Character chat messages.";
public string Help => "ooc <text>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length < 1)
return;
var message = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(message))
return;
var chat = IoCManager.Resolve<IChatManager>();
chat.SendOOC(player, message);
}
}
[AdminCommand(AdminFlags.Admin)]
internal class AdminChatCommand : IClientCommand
{
public string Command => "asay";
public string Description => "Send chat messages to the private admin chat channel.";
public string Help => "asay <text>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length < 1)
return;
var message = string.Join(" ", args).Trim();
if (string.IsNullOrEmpty(message))
return;
var chat = IoCManager.Resolve<IChatManager>();
chat.SendAdminChat(player, message);
}
}
[AnyCommand]
internal class SuicideCommand : IClientCommand
{
@@ -136,7 +35,7 @@ namespace Content.Server.Chat
private void DealDamage(ISuicideAct suicide, IChatManager chat, IDamageableComponent damageableComponent, IEntity source, IEntity target)
{
SuicideKind kind = suicide.Suicide(target, chat);
var kind = suicide.Suicide(target, chat);
if (kind != SuicideKind.Special)
{
damageableComponent.ChangeDamage(kind switch
@@ -158,23 +57,37 @@ namespace Content.Server.Chat
}
}
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player == null)
{
shell.SendText(player, "You cannot run this command from the server.");
return;
}
if (player.Status != SessionStatus.InGame)
return;
var chat = IoCManager.Resolve<IChatManager>();
var owner = player.ContentData().Mind.OwnedMob.Owner;
var owner = player.ContentData()?.Mind?.OwnedMob.Owner;
if (owner == null)
{
shell.SendText(player, "You don't have a mind!");
return;
}
var dmgComponent = owner.GetComponent<IDamageableComponent>();
//TODO: needs to check if the mob is actually alive
//TODO: maybe set a suicided flag to prevent ressurection?
//TODO: maybe set a suicided flag to prevent resurrection?
// Held item suicide
var handsComponent = owner.GetComponent<HandsComponent>();
var itemComponent = handsComponent.GetActiveHand;
if (itemComponent != null)
{
ISuicideAct suicide = itemComponent.Owner.GetAllComponents<ISuicideAct>().FirstOrDefault();
var suicide = itemComponent.Owner.GetAllComponents<ISuicideAct>().FirstOrDefault();
if (suicide != null)
{
DealDamage(suicide, chat, dmgComponent, itemComponent.Owner, owner);
@@ -182,8 +95,9 @@ namespace Content.Server.Chat
}
}
// Get all entities in range of the suicider
var entities = owner.EntityManager.GetEntitiesInRange(owner, 1, true);
if (entities.Count() > 0)
var entities = owner.EntityManager.GetEntitiesInRange(owner, 1, true).ToArray();
if (entities.Length > 0)
{
foreach (var entity in entities)
{

View File

@@ -0,0 +1,27 @@
#nullable enable
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
namespace Content.Server.Commands.Damage
{
[AdminCommand(AdminFlags.Fun)]
public class AddDamageFlagCommand : DamageFlagCommand
{
public override string Command => "adddamageflag";
public override string Description => "Adds a damage flag to your entity or another.";
public override string Help => $"Usage: {Command} <flag> / {Command} <entityUid> <flag>";
public override void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (!TryGetEntity(shell, player, args, true, out var entity, out var flag, out var damageable))
{
return;
}
damageable.AddFlag(flag);
shell.SendText(player, $"Added damage flag {flag} to entity {entity.Name}");
}
}
}

View File

@@ -1,18 +1,14 @@
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using Content.Server.Administration;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Administration;
using Content.Shared.GameObjects.Components.Damage;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.GameObjects.Components.Damage
namespace Content.Server.Commands.Damage
{
public abstract class DamageFlagCommand : IClientCommand
{
@@ -117,100 +113,4 @@ namespace Content.Server.GameObjects.Components.Damage
return true;
}
}
[AdminCommand(AdminFlags.Fun)]
public class AddDamageFlagCommand : DamageFlagCommand
{
public override string Command => "adddamageflag";
public override string Description => "Adds a damage flag to your entity or another.";
public override string Help => $"Usage: {Command} <flag> / {Command} <entityUid> <flag>";
public override void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (!TryGetEntity(shell, player, args, true, out var entity, out var flag, out var damageable))
{
return;
}
damageable.AddFlag(flag);
shell.SendText(player, $"Added damage flag {flag} to entity {entity.Name}");
}
}
[AdminCommand(AdminFlags.Fun)]
public class RemoveDamageFlagCommand : DamageFlagCommand
{
public override string Command => "removedamageflag";
public override string Description => "Removes a damage flag from your entity or another.";
public override string Help => $"Usage: {Command} <flag> / {Command} <entityUid> <flag>";
public override void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (!TryGetEntity(shell, player, args, false, out var entity, out var flag, out var damageable))
{
return;
}
damageable.RemoveFlag(flag);
shell.SendText(player, $"Removed damage flag {flag} from entity {entity.Name}");
}
}
[AdminCommand(AdminFlags.Admin)]
public class GodModeCommand : IClientCommand
{
public string Command => "godmode";
public string Description => "Makes your entity or another invulnerable to almost anything. May have irreversible changes.";
public string Help => $"Usage: {Command} / {Command} <entityUid>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
IEntity entity;
switch (args.Length)
{
case 0:
if (player == null)
{
shell.SendText(player, "An entity needs to be specified when the command isn't used by a player.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "An entity needs to be specified when you aren't attached to an entity.");
return;
}
entity = player.AttachedEntity;
break;
case 1:
if (!EntityUid.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} isn't a valid entity id.");
return;
}
var entityManager = IoCManager.Resolve<IEntityManager>();
if (!entityManager.TryGetEntity(id, out var parsedEntity))
{
shell.SendText(player, $"No entity found with id {id}.");
return;
}
entity = parsedEntity;
break;
default:
shell.SendText(player, Help);
return;
}
var godmodeSystem = EntitySystem.Get<GodmodeSystem>();
var enabled = godmodeSystem.ToggleGodmode(entity);
shell.SendText(player, enabled
? $"Enabled godmode for entity {entity.Name} with id {entity.Uid}"
: $"Disabled godmode for entity {entity.Name} with id {entity.Uid}");
}
}
}

View File

@@ -0,0 +1,71 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Damage
{
[AdminCommand(AdminFlags.Admin)]
public class GodModeCommand : IClientCommand
{
public string Command => "godmode";
public string Description => "Makes your entity or another invulnerable to almost anything. May have irreversible changes.";
public string Help => $"Usage: {Command} / {Command} <entityUid>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
IEntity entity;
switch (args.Length)
{
case 0:
if (player == null)
{
shell.SendText(player, "An entity needs to be specified when the command isn't used by a player.");
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "An entity needs to be specified when you aren't attached to an entity.");
return;
}
entity = player.AttachedEntity;
break;
case 1:
if (!EntityUid.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} isn't a valid entity id.");
return;
}
var entityManager = IoCManager.Resolve<IEntityManager>();
if (!entityManager.TryGetEntity(id, out var parsedEntity))
{
shell.SendText(player, $"No entity found with id {id}.");
return;
}
entity = parsedEntity;
break;
default:
shell.SendText(player, Help);
return;
}
var godmodeSystem = EntitySystem.Get<GodmodeSystem>();
var enabled = godmodeSystem.ToggleGodmode(entity);
shell.SendText(player, enabled
? $"Enabled godmode for entity {entity.Name} with id {entity.Uid}"
: $"Disabled godmode for entity {entity.Name} with id {entity.Uid}");
}
}
}

View File

@@ -0,0 +1,27 @@
#nullable enable
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
namespace Content.Server.Commands.Damage
{
[AdminCommand(AdminFlags.Fun)]
public class RemoveDamageFlagCommand : DamageFlagCommand
{
public override string Command => "removedamageflag";
public override string Description => "Removes a damage flag from your entity or another.";
public override string Help => $"Usage: {Command} <flag> / {Command} <entityUid> <flag>";
public override void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (!TryGetEntity(shell, player, args, false, out var entity, out var flag, out var damageable))
{
return;
}
damageable.RemoveFlag(flag);
shell.SendText(player, $"Removed damage flag {flag} from entity {entity.Name}");
}
}
}

View File

@@ -1,5 +1,6 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Disposal;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
@@ -8,7 +9,7 @@ using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
namespace Content.Server.GameObjects.Components.Disposal
namespace Content.Server.Commands.Disposal
{
[AdminCommand(AdminFlags.Debug)]
public class TubeConnectionsCommand : IClientCommand

View File

@@ -0,0 +1,54 @@
using System;
using Content.Server.Administration;
using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server)]
class DelayStartCommand : IClientCommand
{
public string Command => "delaystart";
public string Description => "Delays the round start.";
public string Help => $"Usage: {Command} <seconds>\nPauses/Resumes the countdown if no argument is provided.";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "This can only be executed while the game is in the pre-round lobby.");
return;
}
if (args.Length == 0)
{
var paused = ticker.TogglePause();
shell.SendText(player, paused ? "Paused the countdown." : "Resumed the countdown.");
return;
}
if (args.Length != 1)
{
shell.SendText(player, "Need zero or one arguments.");
return;
}
if (!uint.TryParse(args[0], out var seconds) || seconds == 0)
{
shell.SendText(player, $"{args[0]} isn't a valid amount of seconds.");
return;
}
var time = TimeSpan.FromSeconds(seconds);
if (!ticker.DelayStart(time))
{
shell.SendText(player, "An unknown error has occurred.");
}
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Content.Server.Administration;
using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server)]
class EndRoundCommand : IClientCommand
{
public string Command => "endround";
public string Description => "Ends the round and moves the server to PostRound.";
public string Help => String.Empty;
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.InRound)
{
shell.SendText(player, "This can only be executed while the game is in a round.");
return;
}
ticker.EndRound();
}
}
}

View File

@@ -0,0 +1,44 @@
using Content.Server.Administration;
using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server)]
class ForcePresetCommand : IClientCommand
{
public string Command => "forcepreset";
public string Description => "Forces a specific game preset to start for the current lobby.";
public string Help => $"Usage: {Command} <preset>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "This can only be executed while the game is in the pre-round lobby.");
return;
}
if (args.Length != 1)
{
shell.SendText(player, "Need exactly one argument.");
return;
}
var name = args[0];
if (!ticker.TryGetPreset(name, out var type))
{
shell.SendText(player, $"No preset exists with name {name}.");
return;
}
ticker.SetStartPreset(type, true);
shell.SendText(player, $"Forced the game to start with preset {name}.");
}
}
}

View File

@@ -0,0 +1,58 @@
using System.Collections.Generic;
using Content.Server.Administration;
using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Roles;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
namespace Content.Server.Commands.GameTicking
{
[AnyCommand]
class JoinGameCommand : IClientCommand
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public string Command => "joingame";
public string Description => "";
public string Help => "";
public JoinGameCommand()
{
IoCManager.InjectDependencies(this);
}
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var output = string.Join(".", args);
if (player == null)
{
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel == GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "Round has not started.");
return;
}
else if(ticker.RunLevel == GameRunLevel.InRound)
{
string ID = args[0];
var positions = ticker.GetAvailablePositions();
if(positions.GetValueOrDefault(ID, 0) == 0) //n < 0 is treated as infinite
{
var jobPrototype = _prototypeManager.Index<JobPrototype>(ID);
shell.SendText(player, $"{jobPrototype.Name} has no available slots.");
return;
}
ticker.MakeJoinGame(player, args[0].ToString());
return;
}
ticker.MakeJoinGame(player, null);
}
}
}

View File

@@ -0,0 +1,68 @@
using System.Linq;
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Utility;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server | AdminFlags.Mapping)]
class MappingCommand : IClientCommand
{
public string Command => "mapping";
public string Description => "Creates and teleports you to a new uninitialized map for mapping.";
public string Help => $"Usage: {Command} <mapname> / {Command} <id> <mapname>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player == null)
{
shell.SendText(player, "Only players can use this command");
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
int mapId;
string mapName;
switch (args.Length)
{
case 1:
if (player.AttachedEntity == null)
{
shell.SendText(player, "The map name argument cannot be omitted if you have no entity.");
return;
}
mapId = (int) mapManager.NextMapId();
mapName = args[0];
break;
case 2:
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
mapId = id;
mapName = args[1];
break;
default:
shell.SendText(player, Help);
return;
}
shell.ExecuteCommand(player, $"addmap {mapId} false");
shell.ExecuteCommand(player, $"loadbp {mapId} \"{CommandParsing.Escape(mapName)}\"");
shell.ExecuteCommand(player, "aghost");
shell.ExecuteCommand(player, $"tp 0 0 {mapId}");
var newGridId = mapManager.GetAllGrids().Max(g => (int) g.Index);
shell.SendText(player, $"Created unloaded map from file {mapName} with id {mapId}. Use \"savebp {newGridId} foo.yml\" to save the new grid as a map.");
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using Content.Server.Administration;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server)]
public class NewRoundCommand : IClientCommand
{
public string Command => "restartround";
public string Description => "Moves the server from PostRound to a new PreRoundLobby.";
public string Help => String.Empty;
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.RestartRound();
}
}
}

View File

@@ -0,0 +1,27 @@
using Content.Server.Administration;
using Content.Server.Interfaces.GameTicking;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AnyCommand]
class ObserveCommand : IClientCommand
{
public string Command => "observe";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player == null)
{
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.MakeObserve(player);
}
}
}

View File

@@ -0,0 +1,61 @@
using Content.Server.Interfaces.GameTicking;
using Content.Server.Players;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Content.Server.Commands.GameTicking
{
class RespawnCommand : IClientCommand
{
public string Command => "respawn";
public string Description => "Respawns a player, kicking them back to the lobby.";
public string Help => "respawn [player]";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length > 1)
{
shell.SendText(player, "Must provide <= 1 argument.");
return;
}
var playerMgr = IoCManager.Resolve<IPlayerManager>();
var ticker = IoCManager.Resolve<IGameTicker>();
NetUserId userId;
if (args.Length == 0)
{
if (player == null)
{
shell.SendText((IPlayerSession)null, "If not a player, an argument must be given.");
return;
}
userId = player.UserId;
}
else if (!playerMgr.TryGetUserId(args[0], out userId))
{
shell.SendText(player, "Unknown player");
return;
}
if (!playerMgr.TryGetSessionById(userId, out var targetPlayer))
{
if (!playerMgr.TryGetPlayerData(userId, out var data))
{
shell.SendText(player, "Unknown player");
return;
}
data.ContentData().WipeMind();
shell.SendText(player,
"Player is not currently online, but they will respawn if they come back online");
return;
}
ticker.Respawn(targetPlayer);
}
}
}

View File

@@ -0,0 +1,30 @@
using Content.Server.Administration;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server)]
class SetGamePresetCommand : IClientCommand
{
public string Command => "setgamepreset";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Need exactly one argument.");
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.SetStartPreset(args[0]);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using Content.Server.Administration;
using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server)]
class StartRoundCommand : IClientCommand
{
public string Command => "startround";
public string Description => "Ends PreRoundLobby state and starts the round.";
public string Help => String.Empty;
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "This can only be executed while the game is in the pre-round lobby.");
return;
}
ticker.StartRound();
}
}
}

View File

@@ -0,0 +1,112 @@
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Maps;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Mapping)]
class TileWallsCommand : IClientCommand
{
// ReSharper disable once StringLiteralTypo
public string Command => "tilewalls";
public string Description => "Puts an underplating tile below every wall on a grid.";
public string Help => $"Usage: {Command} <gridId> | {Command}";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
GridId gridId;
switch (args.Length)
{
case 0:
if (player?.AttachedEntity == null)
{
shell.SendText((IPlayerSession) null, "Only a player can run this command.");
return;
}
gridId = player.AttachedEntity.Transform.GridID;
break;
case 1:
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
gridId = new GridId(id);
break;
default:
shell.SendText(player, Help);
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
if (!mapManager.TryGetGrid(gridId, out var grid))
{
shell.SendText(player, $"No grid exists with id {gridId}");
return;
}
var entityManager = IoCManager.Resolve<IEntityManager>();
if (!entityManager.TryGetEntity(grid.GridEntityId, out var gridEntity))
{
shell.SendText(player, $"Grid {gridId} doesn't have an associated grid entity.");
return;
}
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
var underplating = tileDefinitionManager["underplating"];
var underplatingTile = new Tile(underplating.TileId);
var changed = 0;
foreach (var childUid in gridEntity.Transform.ChildEntityUids)
{
if (!entityManager.TryGetEntity(childUid, out var childEntity))
{
continue;
}
var prototype = childEntity.Prototype;
while (true)
{
if (prototype?.Parent == null)
{
break;
}
prototype = prototype.Parent;
}
if (prototype?.ID != "base_wall")
{
continue;
}
if (!childEntity.TryGetComponent(out SnapGridComponent snapGrid))
{
continue;
}
var tile = grid.GetTileRef(childEntity.Transform.Coordinates);
var tileDef = (ContentTileDefinition) tileDefinitionManager[tile.Tile.TypeId];
if (tileDef.Name == "underplating")
{
continue;
}
grid.SetTile(childEntity.Transform.Coordinates, underplatingTile);
changed++;
}
shell.SendText(player, $"Changed {changed} tiles.");
}
}
}

View File

@@ -0,0 +1,38 @@
using Content.Server.Administration;
using Content.Server.Interfaces.GameTicking;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AdminCommand(AdminFlags.Server)]
class ToggleDisallowLateJoinCommand : IClientCommand
{
public string Command => "toggledisallowlatejoin";
public string Description => "Allows or disallows latejoining during mid-game.";
public string Help => $"Usage: {Command} <disallow>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Need exactly one argument.");
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
if (bool.TryParse(args[0], out var result))
{
ticker.ToggleDisallowLateJoin(bool.Parse(args[0]));
shell.SendText(player, result ? "Late joining has been disabled." : "Late joining has been enabled.");
}
else
{
shell.SendText(player, "Invalid argument.");
}
}
}
}

View File

@@ -0,0 +1,27 @@
using Content.Server.Administration;
using Content.Server.Interfaces.GameTicking;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.GameTicking
{
[AnyCommand]
class ToggleReadyCommand : IClientCommand
{
public string Command => "toggleready";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player == null)
{
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.ToggleReady(player, bool.Parse(args[0]));
}
}
}

View File

@@ -0,0 +1,57 @@
#nullable enable
using System.Linq;
using Content.Server.Administration;
using Content.Server.GameObjects.Components;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.GameObjects;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Interactable
{
[AdminCommand(AdminFlags.Debug)]
class AnchorCommand : IClientCommand
{
public string Command => "anchor";
public string Description => "Anchors all entities in a radius around the user";
public string Help => $"Usage: {Command} <radius>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player?.AttachedEntity == null)
{
return;
}
if (args.Length != 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var radius))
{
shell.SendText(player, $"{args[0]} isn't a valid integer.");
return;
}
if (radius < 0)
{
shell.SendText(player, "Radius must be positive.");
return;
}
var serverEntityManager = IoCManager.Resolve<IServerEntityManager>();
var entities = serverEntityManager.GetEntitiesInRange(player.AttachedEntity, radius).ToList();
foreach (var entity in entities)
{
if (entity.TryGetComponent(out AnchorableComponent? anchorable))
{
_ = anchorable.TryAnchor(player.AttachedEntity, force: true);
}
}
}
}
}

View File

@@ -0,0 +1,71 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Interactable;
using Content.Shared.Administration;
using Content.Shared.Maps;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.Commands.Interactable
{
/// <summary>
/// <see cref="TilePryingComponent.TryPryTile"/>
/// </summary>
[AdminCommand(AdminFlags.Debug)]
class TilePryCommand : IClientCommand
{
public string Command => "tilepry";
public string Description => "Pries up all tiles in a radius around the user.";
public string Help => $"Usage: {Command} <radius>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player?.AttachedEntity == null)
{
return;
}
if (args.Length != 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var radius))
{
shell.SendText(player, $"{args[0]} isn't a valid integer.");
return;
}
if (radius < 0)
{
shell.SendText(player, "Radius must be positive.");
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
var playerGrid = player.AttachedEntity.Transform.GridID;
var mapGrid = mapManager.GetGrid(playerGrid);
var playerPosition = player.AttachedEntity.Transform.Coordinates;
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
for (var i = -radius; i <= radius; i++)
{
for (var j = -radius; j <= radius; j++)
{
var tile = mapGrid.GetTileRef(playerPosition.Offset((i, j)));
var coordinates = mapGrid.GridTileToLocal(tile.GridIndices);
var tileDef = (ContentTileDefinition) tileDefinitionManager[tile.Tile.TypeId];
if (!tileDef.CanCrowbar) continue;
var underplating = tileDefinitionManager["underplating"];
mapGrid.SetTile(coordinates, new Tile(underplating.TileId));
}
}
}
}
}

View File

@@ -0,0 +1,57 @@
#nullable enable
using System.Linq;
using Content.Server.Administration;
using Content.Server.GameObjects.Components;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.GameObjects;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Interactable
{
[AdminCommand(AdminFlags.Debug)]
class UnAnchorCommand : IClientCommand
{
public string Command => "unanchor";
public string Description => "Unanchors all anchorable entities in a radius around the user";
public string Help => $"Usage: {Command} <radius>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player?.AttachedEntity == null)
{
return;
}
if (args.Length != 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var radius))
{
shell.SendText(player, $"{args[0]} isn't a valid integer.");
return;
}
if (radius < 0)
{
shell.SendText(player, "Radius must be positive.");
return;
}
var serverEntityManager = IoCManager.Resolve<IServerEntityManager>();
var entities = serverEntityManager.GetEntitiesInRange(player.AttachedEntity, radius).ToList();
foreach (var entity in entities)
{
if (entity.TryGetComponent(out AnchorableComponent? anchorable))
{
_ = anchorable.TryUnAnchor(player.AttachedEntity, force: true);
}
}
}
}
}

View File

@@ -0,0 +1,49 @@
using Content.Server.Administration;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.Commands.MachineLinking
{
[AdminCommand(AdminFlags.Debug)]
public class SignalLinkerCommand : IClientCommand
{
public string Command => "signallink";
public string Description => "Turns on signal linker mode. Click a transmitter to tune that signal and then click on each receiver to tune them to the transmitter signal.";
public string Help => "signallink (on/off)";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
bool? enable = null;
if (args.Length > 0)
{
if (args[0] == "on")
enable = true;
else if (args[0] == "off")
enable = false;
else if (bool.TryParse(args[0], out var boolean))
enable = boolean;
else if (int.TryParse(args[0], out var num))
{
if (num == 1)
enable = true;
else if (num == 0)
enable = false;
}
}
if (!IoCManager.Resolve<IEntitySystemManager>().TryGetEntitySystem<SignalLinkerSystem>(out var system))
{
return;
}
var ret = system.SignalLinkerKeybind(player.UserId, enable);
shell.SendText(player, ret ? "Enabled" : "Disabled");
}
}
}

View File

@@ -0,0 +1,33 @@
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
namespace Content.Server.Commands.Mobs
{
[AdminCommand(AdminFlags.Debug)]
public class AddOverlayCommand : IClientCommand
{
public string Command => "addoverlay";
public string Description => "Adds an overlay by its ID";
public string Help => "addoverlay <id>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Expected 1 argument.");
return;
}
if (player?.AttachedEntity != null)
{
if (player.AttachedEntity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent))
{
overlayEffectsComponent.AddOverlay(args[0]);
}
}
}
}
}

View File

@@ -0,0 +1,45 @@
using Content.Server.Administration;
using Content.Server.Mobs.Roles;
using Content.Server.Players;
using Content.Shared.Administration;
using Content.Shared.Roles;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
namespace Content.Server.Commands.Mobs
{
[AdminCommand(AdminFlags.Fun)]
public class AddRoleCommand : IClientCommand
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public string Command => "addrole";
public string Description => "Adds a role to a player's mind.";
public string Help => "addrole <session ID> <Role Type>\nThat role type is the actual C# type name.";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
var mind = data.ContentData().Mind;
var role = new Job(mind, _prototypeManager.Index<JobPrototype>(args[1]));
mind.AddRole(role);
}
else
{
shell.SendText(player, "Can't find that mind");
}
}
}
}

View File

@@ -0,0 +1,48 @@
using System.Text;
using Content.Server.Administration;
using Content.Server.Players;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Mobs
{
[AdminCommand(AdminFlags.Admin)]
public class MindInfoCommand : IClientCommand
{
public string Command => "mindinfo";
public string Description => "Lists info for the mind of a specific player.";
public string Help => "mindinfo <session ID>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Expected exactly 1 argument.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetSessionByUsername(args[0], out var data))
{
var mind = data.ContentData().Mind;
var builder = new StringBuilder();
builder.AppendFormat("player: {0}, mob: {1}\nroles: ", mind.UserId, mind.OwnedMob?.Owner?.Uid);
foreach (var role in mind.AllRoles)
{
builder.AppendFormat("{0} ", role.Name);
}
shell.SendText(player, builder.ToString());
}
else
{
shell.SendText(player, "Can't find that mind");
}
}
}
}

View File

@@ -0,0 +1,33 @@
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
namespace Content.Server.Commands.Mobs
{
[AdminCommand(AdminFlags.Debug)]
public class RemoveOverlayCommand : IClientCommand
{
public string Command => "rmoverlay";
public string Description => "Removes an overlay by its ID";
public string Help => "rmoverlay <id>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Expected 1 argument.");
return;
}
if (player?.AttachedEntity != null)
{
if (player.AttachedEntity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent))
{
overlayEffectsComponent.RemoveOverlay(args[0]);
}
}
}
}
}

View File

@@ -0,0 +1,45 @@
using Content.Server.Administration;
using Content.Server.Mobs.Roles;
using Content.Server.Players;
using Content.Shared.Administration;
using Content.Shared.Roles;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
namespace Content.Server.Commands.Mobs
{
[AdminCommand(AdminFlags.Fun)]
public class RemoveRoleCommand : IClientCommand
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public string Command => "rmrole";
public string Description => "Removes a role from a player's mind.";
public string Help => "rmrole <session ID> <Role Type>\nThat role type is the actual C# type name.";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
var mind = data.ContentData().Mind;
var role = new Job(mind, _prototypeManager.Index<JobPrototype>(args[1]));
mind.RemoveRole(role);
}
else
{
shell.SendText(player, "Can't find that mind");
}
}
}
}

View File

@@ -0,0 +1,30 @@
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Interfaces;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Notify
{
[AdminCommand(AdminFlags.Debug)]
public class PopupMsgCommand : IClientCommand
{
public string Command => "srvpopupmsg";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var entityMgr = IoCManager.Resolve<IEntityManager>();
var source = EntityUid.Parse(args[0]);
var viewer = EntityUid.Parse(args[1]);
var msg = args[2];
entityMgr.GetEntity(source).PopupMessage(entityMgr.GetEntity(viewer), msg);
}
}
}

View File

@@ -0,0 +1,56 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.Objectives;
using Content.Server.Players;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
namespace Content.Server.Commands.Objectives
{
[AdminCommand(AdminFlags.Admin)]
public class AddObjectiveCommand : IClientCommand
{
public string Command => "addobjective";
public string Description => "Adds an objective to the player's mind.";
public string Help => "addobjective <username> <objectiveID>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (!mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
shell.SendText(player, "Can't find the playerdata.");
return;
}
var mind = data.ContentData()?.Mind;
if (mind == null)
{
shell.SendText(player, "Can't find the mind.");
return;
}
if (!IoCManager.Resolve<IPrototypeManager>()
.TryIndex<ObjectivePrototype>(args[1], out var objectivePrototype))
{
shell.SendText(player, $"Can't find matching ObjectivePrototype {objectivePrototype}");
return;
}
if (!mind.TryAddObjective(objectivePrototype))
{
shell.SendText(player, "Objective requirements dont allow that objective to be added.");
}
}
}
}

View File

@@ -0,0 +1,51 @@
#nullable enable
using System.Linq;
using Content.Server.Administration;
using Content.Server.Players;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Objectives
{
[AdminCommand(AdminFlags.Admin)]
public class ListObjectivesCommand : IClientCommand
{
public string Command => "lsobjectives";
public string Description => "Lists all objectives in a players mind.";
public string Help => "lsobjectives [<username>]";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
IPlayerData? data;
if (args.Length == 0 && player != null)
{
data = player.Data;
}
else if (player == null || !IoCManager.Resolve<IPlayerManager>().TryGetPlayerDataByUsername(args[0], out data))
{
shell.SendText(player, "Can't find the playerdata.");
return;
}
var mind = data.ContentData()?.Mind;
if (mind == null)
{
shell.SendText(player, "Can't find the mind.");
return;
}
shell.SendText(player, $"Objectives for player {data.UserId}:");
var objectives = mind.AllObjectives.ToList();
if (objectives.Count == 0)
{
shell.SendText(player, "None.");
}
for (var i = 0; i < objectives.Count; i++)
{
shell.SendText(player, $"- [{i}] {objectives[i]}");
}
}
}
}

View File

@@ -0,0 +1,53 @@
#nullable enable
using Content.Server.Administration;
using Content.Server.Players;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Objectives
{
[AdminCommand(AdminFlags.Admin)]
public class RemoveObjectiveCommand : IClientCommand
{
public string Command => "rmobjective";
public string Description => "Removes an objective from the player's mind.";
public string Help => "rmobjective <username> <index>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
var mind = data.ContentData()?.Mind;
if (mind == null)
{
shell.SendText(player, "Can't find the mind.");
return;
}
if (int.TryParse(args[1], out var i))
{
shell.SendText(player,
mind.TryRemoveObjective(i)
? "Objective successfully removed!"
: "Objective removing failed. Maybe the index is out of bounds? Check lsobjectives!");
}
else
{
shell.SendText(player, $"Invalid index {args[1]}!");
}
}
else
{
shell.SendText(player, "Can't find the playerdata.");
}
}
}
}

View File

@@ -1,4 +1,4 @@
using Content.Server.Administration;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.Interfaces.GameTicking;
@@ -11,7 +11,7 @@ using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.Observer
namespace Content.Server.Commands.Observer
{
[AnyCommand]
public class Ghost : IClientCommand

View File

@@ -0,0 +1,86 @@
#nullable enable
using System;
using System.Linq;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs.Speech;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.Commands.Speech
{
[AdminCommand(AdminFlags.Fun)]
public class AddAccent : IClientCommand
{
public string Command => "addaccent";
public string Description => "Add a speech component to the current player";
public string Help => $"{Command} <component>/?";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player?.AttachedEntity == null)
{
shell.SendText(player, "You don't have an entity!");
return;
}
if (args.Length == 0)
{
shell.SendText(player, Help);
return;
}
var compFactory = IoCManager.Resolve<IComponentFactory>();
if (args[0] == "?")
{
// Get all components that implement the ISpeechComponent except
var speeches = compFactory.GetAllRefTypes()
.Where(c => typeof(IAccentComponent).IsAssignableFrom(c) && c.IsClass);
var msg = "";
foreach(var s in speeches)
{
msg += $"{compFactory.GetRegistration(s).Name}\n";
}
shell.SendText(player, msg);
}
else
{
var name = args[0];
// Try to get the Component
Type type;
try
{
var comp = compFactory.GetComponent(name);
type = comp.GetType();
}
catch (Exception)
{
shell.SendText(player, $"Accent {name} not found. Try {Command} ? to get a list of all appliable accents.");
return;
}
// Check if that already exists
try
{
var comp = player.AttachedEntity.GetComponent(type);
shell.SendText(player, "You already have this accent!");
return;
}
catch (Exception)
{
// Accent not found
}
// Generic fuckery
var ensure = typeof(IEntity).GetMethod("AddComponent");
if (ensure == null)
return;
var method = ensure.MakeGenericMethod(type);
method.Invoke(player.AttachedEntity, null);
}
}
}
}

View File

@@ -7,7 +7,7 @@ using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Localization;
namespace Content.Server.StationEvents
namespace Content.Server.Commands.StationEvents
{
[AdminCommand(AdminFlags.Server)]
public sealed class StationEventCommand : IClientCommand

View File

@@ -1,5 +1,5 @@
#nullable enable
using Content.Server.Observer;
using Content.Server.Commands.Observer;
using Content.Shared.GameObjects.Components.Body;
using Content.Shared.GameObjects.Components.Body.Part;
using Content.Shared.GameObjects.Components.Damage;

View File

@@ -1,163 +0,0 @@
#nullable enable
using System.Linq;
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Maps;
using JetBrains.Annotations;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.GameObjects;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Content.Server.GameObjects.Components.Interactable
{
/// <summary>
/// <see cref="TilePryingComponent.TryPryTile"/>
/// </summary>
[AdminCommand(AdminFlags.Debug)]
class TilePryCommand : IClientCommand
{
public string Command => "tilepry";
public string Description => "Pries up all tiles in a radius around the user.";
public string Help => $"Usage: {Command} <radius>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player?.AttachedEntity == null)
{
return;
}
if (args.Length != 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var radius))
{
shell.SendText(player, $"{args[0]} isn't a valid integer.");
return;
}
if (radius < 0)
{
shell.SendText(player, "Radius must be positive.");
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
var playerGrid = player.AttachedEntity.Transform.GridID;
var mapGrid = mapManager.GetGrid(playerGrid);
var playerPosition = player.AttachedEntity.Transform.Coordinates;
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
for (var i = -radius; i <= radius; i++)
{
for (var j = -radius; j <= radius; j++)
{
var tile = mapGrid.GetTileRef(playerPosition.Offset((i, j)));
var coordinates = mapGrid.GridTileToLocal(tile.GridIndices);
var tileDef = (ContentTileDefinition) tileDefinitionManager[tile.Tile.TypeId];
if (!tileDef.CanCrowbar) continue;
var underplating = tileDefinitionManager["underplating"];
mapGrid.SetTile(coordinates, new Tile(underplating.TileId));
}
}
}
}
[AdminCommand(AdminFlags.Debug)]
class AnchorCommand : IClientCommand
{
public string Command => "anchor";
public string Description => "Anchors all entities in a radius around the user";
public string Help => $"Usage: {Command} <radius>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player?.AttachedEntity == null)
{
return;
}
if (args.Length != 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var radius))
{
shell.SendText(player, $"{args[0]} isn't a valid integer.");
return;
}
if (radius < 0)
{
shell.SendText(player, "Radius must be positive.");
return;
}
var serverEntityManager = IoCManager.Resolve<IServerEntityManager>();
var entities = serverEntityManager.GetEntitiesInRange(player.AttachedEntity, radius).ToList();
foreach (var entity in entities)
{
if (entity.TryGetComponent(out AnchorableComponent? anchorable))
{
_ = anchorable.TryAnchor(player.AttachedEntity, force: true);
}
}
}
}
[AdminCommand(AdminFlags.Debug)]
class UnAnchorCommand : IClientCommand
{
public string Command => "unanchor";
public string Description => "Unanchors all anchorable entities in a radius around the user";
public string Help => $"Usage: {Command} <radius>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (player?.AttachedEntity == null)
{
return;
}
if (args.Length != 1)
{
shell.SendText(player, Help);
return;
}
if (!int.TryParse(args[0], out var radius))
{
shell.SendText(player, $"{args[0]} isn't a valid integer.");
return;
}
if (radius < 0)
{
shell.SendText(player, "Radius must be positive.");
return;
}
var serverEntityManager = IoCManager.Resolve<IServerEntityManager>();
var entities = serverEntityManager.GetEntitiesInRange(player.AttachedEntity, radius).ToList();
foreach (var entity in entities)
{
if (entity.TryGetComponent(out AnchorableComponent? anchorable))
{
_ = anchorable.TryUnAnchor(player.AttachedEntity, force: true);
}
}
}
}
}

View File

@@ -1,16 +1,9 @@
using System;
using Content.Server.Administration;
using Content.Server.Commands;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.Administration;
using Content.Shared.Alert;
using Content.Shared.GameObjects.Components.Mobs;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Players;
@@ -89,82 +82,4 @@ namespace Content.Server.GameObjects.Components.Mobs
}
}
}
[AdminCommand(AdminFlags.Debug)]
public sealed class ShowAlert : IClientCommand
{
public string Command => "showalert";
public string Description => "Shows an alert for a player, defaulting to current player";
public string Help => "showalert <alertType> <severity, -1 if no severity> <name or userID, omit for current player>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var attachedEntity = player.AttachedEntity;
if (args.Length > 2)
{
var target = args[2];
if (!Commands.CommandUtils.TryGetAttachedEntityByUsernameOrId(shell, target, player, out attachedEntity)) return;
}
if (!CommandUtils.ValidateAttachedEntity(shell, player, attachedEntity)) return;
if (!attachedEntity.TryGetComponent(out ServerAlertsComponent alertsComponent))
{
shell.SendText(player, "user has no alerts component");
return;
}
var alertType = args[0];
var severity = args[1];
var alertMgr = IoCManager.Resolve<AlertManager>();
if (!alertMgr.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
{
shell.SendText(player, "unrecognized alertType " + alertType);
return;
}
if (!short.TryParse(severity, out var sevint))
{
shell.SendText(player, "invalid severity " + sevint);
return;
}
alertsComponent.ShowAlert(alert.AlertType, sevint == -1 ? (short?) null : sevint);
}
}
[AdminCommand(AdminFlags.Debug)]
public sealed class ClearAlert : IClientCommand
{
public string Command => "clearalert";
public string Description => "Clears an alert for a player, defaulting to current player";
public string Help => "clearalert <alertType> <name or userID, omit for current player>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var attachedEntity = player.AttachedEntity;
if (args.Length > 1)
{
var target = args[1];
if (!CommandUtils.TryGetAttachedEntityByUsernameOrId(shell, target, player, out attachedEntity)) return;
}
if (!CommandUtils.ValidateAttachedEntity(shell, player, attachedEntity)) return;
if (!attachedEntity.TryGetComponent(out ServerAlertsComponent alertsComponent))
{
shell.SendText(player, "user has no alerts component");
return;
}
var alertType = args[0];
var alertMgr = IoCManager.Resolve<AlertManager>();
if (!alertMgr.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
{
shell.SendText(player, "unrecognized alertType " + alertType);
return;
}
alertsComponent.ClearAlert(alert.AlertType);
}
}
}

View File

@@ -1,13 +1,4 @@
using System;
using System.Linq;
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Server.GameObjects.Components.Mobs.Speech
namespace Content.Server.GameObjects.Components.Mobs.Speech
{
internal interface IAccentComponent
{
@@ -18,79 +9,4 @@ namespace Content.Server.GameObjects.Components.Mobs.Speech
/// <returns>The message after the transformation</returns>
public string Accentuate(string message);
}
[AdminCommand(AdminFlags.Fun)]
public class AddAccent : IClientCommand
{
public string Command => "addaccent";
public string Description => "Add a speech component to the current player";
public string Help => $"{Command} <component>/?";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length == 0)
{
shell.SendText(player, Help);
return;
}
if (player.AttachedEntity == null)
{
shell.SendText(player, "You don't have a player!");
return;
}
var compFactory = IoCManager.Resolve<IComponentFactory>();
if (args[0] == "?")
{
// Get all components that implement the ISpeechComponent except
var speeches = compFactory.GetAllRefTypes()
.Where(c => typeof(IAccentComponent).IsAssignableFrom(c) && c.IsClass);
var msg = "";
foreach(var s in speeches)
{
msg += $"{compFactory.GetRegistration(s).Name}\n";
}
shell.SendText(player, msg);
}
else
{
var name = args[0];
// Try to get the Component
Type type;
try
{
var comp = compFactory.GetComponent(name);
type = comp.GetType();
}
catch (Exception)
{
shell.SendText(player, $"Accent {name} not found. Try {Command} ? to get a list of all appliable accents.");
return;
}
// Check if that already exists
try
{
var comp = player.AttachedEntity.GetComponent(type);
shell.SendText(player, "You already have this accent!");
return;
}
catch (Exception)
{
// Accent not found
}
// Generic fuckery
var ensure = typeof(IEntity).GetMethod("AddComponent");
if (ensure == null)
return;
var method = ensure.MakeGenericMethod(type);
method.Invoke(player.AttachedEntity, null);
}
}
}
}

View File

@@ -1,14 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.AI;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Localization;
namespace Content.Server.GameObjects.EntitySystems.AI
{
@@ -91,88 +84,4 @@ namespace Content.Server.GameObjects.EntitySystems.AI
_hostileFactions[source] = hostileFactions;
}
}
[AdminCommand(AdminFlags.Fun)]
public sealed class FactionCommand : IClientCommand
{
public string Command => "factions";
public string Description => "Update / list factional relationships for NPCs.";
public string Help => "faction <source> <friendly/hostile> target\n" +
"faction <source> list: hostile factions";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length == 0)
{
var result = new StringBuilder();
foreach (Faction value in Enum.GetValues(typeof(Faction)))
{
if (value == Faction.None)
continue;
result.Append(value + "\n");
}
shell.SendText(player, result.ToString());
return;
}
if (args.Length < 2)
{
shell.SendText(player, Loc.GetString("Need more args"));
return;
}
if (!Enum.TryParse(args[0], true, out Faction faction))
{
shell.SendText(player, Loc.GetString("Invalid faction"));
return;
}
Faction targetFaction;
switch (args[1])
{
case "friendly":
if (args.Length < 3)
{
shell.SendText(player, Loc.GetString("Need to supply a target faction"));
return;
}
if (!Enum.TryParse(args[2], true, out targetFaction))
{
shell.SendText(player, Loc.GetString("Invalid target faction"));
return;
}
EntitySystem.Get<AiFactionTagSystem>().MakeFriendly(faction, targetFaction);
shell.SendText(player, Loc.GetString("Command successful"));
break;
case "hostile":
if (args.Length < 3)
{
shell.SendText(player, Loc.GetString("Need to supply a target faction"));
return;
}
if (!Enum.TryParse(args[2], true, out targetFaction))
{
shell.SendText(player, Loc.GetString("Invalid target faction"));
return;
}
EntitySystem.Get<AiFactionTagSystem>().MakeHostile(faction, targetFaction);
shell.SendText(player, Loc.GetString("Command successful"));
break;
case "list":
shell.SendText(player, EntitySystem.Get<AiFactionTagSystem>().GetHostileFactions(faction).ToString());
break;
default:
shell.SendText(player, Loc.GetString("Unknown faction arg"));
break;
}
return;
}
}
}

View File

@@ -144,50 +144,5 @@ namespace Content.Server.GameObjects.EntitySystems.AI
}
public bool ProcessorTypeExists(string name) => _processorTypes.ContainsKey(name);
[AdminCommand(AdminFlags.Fun)]
private class AddAiCommand : IClientCommand
{
public string Command => "addai";
public string Description => "Add an ai component with a given processor to an entity.";
public string Help => "Usage: addai <processorId> <entityId>"
+ "\n processorId: Class that inherits AiLogicProcessor and has an AiLogicProcessor attribute."
+ "\n entityID: Uid of entity to add the AiControllerComponent to. Open its VV menu to find this.";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if(args.Length != 2)
{
shell.SendText(player, "Wrong number of args.");
return;
}
var processorId = args[0];
var entId = new EntityUid(int.Parse(args[1]));
var ent = IoCManager.Resolve<IEntityManager>().GetEntity(entId);
var aiSystem = Get<AiSystem>();
if (!aiSystem.ProcessorTypeExists(processorId))
{
shell.SendText(player, "Invalid processor type. Processor must inherit AiLogicProcessor and have an AiLogicProcessor attribute.");
return;
}
if (ent.HasComponent<AiControllerComponent>())
{
shell.SendText(player, "Entity already has an AI component.");
return;
}
if (ent.HasComponent<IMoverComponent>())
{
ent.RemoveComponent<IMoverComponent>();
}
var comp = ent.AddComponent<AiControllerComponent>();
comp.LogicName = processorId;
shell.SendText(player, "AI component added.");
}
}
}
}

View File

@@ -1,16 +1,10 @@
using System.Collections.Generic;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.MachineLinking;
using Content.Server.GameObjects.EntitySystems.Click;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Players;
@@ -99,43 +93,4 @@ namespace Content.Server.GameObjects.EntitySystems
}
}
[AdminCommand(AdminFlags.Debug)]
public class SignalLinkerCommand : IClientCommand
{
public string Command => "signallink";
public string Description => "Turns on signal linker mode. Click a transmitter to tune that signal and then click on each receiver to tune them to the transmitter signal.";
public string Help => "signallink (on/off)";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
bool? enable = null;
if (args.Length > 0)
{
if (args[0] == "on")
enable = true;
else if (args[0] == "off")
enable = false;
else if (bool.TryParse(args[0], out var boolean))
enable = boolean;
else if (int.TryParse(args[0], out var num))
{
if (num == 1)
enable = true;
else if (num == 0)
enable = false;
}
}
if (!IoCManager.Resolve<IEntitySystemManager>().TryGetEntitySystem<SignalLinkerSystem>(out var system))
{
return;
}
var ret = system.SignalLinkerKeybind(player.UserId, enable);
shell.SendText(player, ret ? "Enabled" : "Disabled");
}
}
}

View File

@@ -1,497 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Server.Administration;
using Content.Server.Interfaces.GameTicking;
using Content.Server.Players;
using Content.Shared.Administration;
using Content.Shared.Maps;
using Content.Shared.Roles;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.GameTicking
{
[AdminCommand(AdminFlags.Server)]
class DelayStartCommand : IClientCommand
{
public string Command => "delaystart";
public string Description => "Delays the round start.";
public string Help => $"Usage: {Command} <seconds>\nPauses/Resumes the countdown if no argument is provided.";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "This can only be executed while the game is in the pre-round lobby.");
return;
}
if (args.Length == 0)
{
var paused = ticker.TogglePause();
shell.SendText(player, paused ? "Paused the countdown." : "Resumed the countdown.");
return;
}
if (args.Length != 1)
{
shell.SendText(player, "Need zero or one arguments.");
return;
}
if (!uint.TryParse(args[0], out var seconds) || seconds == 0)
{
shell.SendText(player, $"{args[0]} isn't a valid amount of seconds.");
return;
}
var time = TimeSpan.FromSeconds(seconds);
if (!ticker.DelayStart(time))
{
shell.SendText(player, "An unknown error has occurred.");
}
}
}
[AdminCommand(AdminFlags.Server)]
class StartRoundCommand : IClientCommand
{
public string Command => "startround";
public string Description => "Ends PreRoundLobby state and starts the round.";
public string Help => String.Empty;
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "This can only be executed while the game is in the pre-round lobby.");
return;
}
ticker.StartRound();
}
}
[AdminCommand(AdminFlags.Server)]
class EndRoundCommand : IClientCommand
{
public string Command => "endround";
public string Description => "Ends the round and moves the server to PostRound.";
public string Help => String.Empty;
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.InRound)
{
shell.SendText(player, "This can only be executed while the game is in a round.");
return;
}
ticker.EndRound();
}
}
[AdminCommand(AdminFlags.Server)]
public class NewRoundCommand : IClientCommand
{
public string Command => "restartround";
public string Description => "Moves the server from PostRound to a new PreRoundLobby.";
public string Help => String.Empty;
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.RestartRound();
}
}
class RespawnCommand : IClientCommand
{
public string Command => "respawn";
public string Description => "Respawns a player, kicking them back to the lobby.";
public string Help => "respawn [player]";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length > 1)
{
shell.SendText(player, "Must provide <= 1 argument.");
return;
}
var playerMgr = IoCManager.Resolve<IPlayerManager>();
var ticker = IoCManager.Resolve<IGameTicker>();
NetUserId userId;
if (args.Length == 0)
{
if (player == null)
{
shell.SendText((IPlayerSession)null, "If not a player, an argument must be given.");
return;
}
userId = player.UserId;
}
else if (!playerMgr.TryGetUserId(args[0], out userId))
{
shell.SendText(player, "Unknown player");
return;
}
if (!playerMgr.TryGetSessionById(userId, out var targetPlayer))
{
if (!playerMgr.TryGetPlayerData(userId, out var data))
{
shell.SendText(player, "Unknown player");
return;
}
data.ContentData().WipeMind();
shell.SendText(player,
"Player is not currently online, but they will respawn if they come back online");
return;
}
ticker.Respawn(targetPlayer);
}
}
[AnyCommand]
class ObserveCommand : IClientCommand
{
public string Command => "observe";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player == null)
{
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.MakeObserve(player);
}
}
[AnyCommand]
class JoinGameCommand : IClientCommand
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public string Command => "joingame";
public string Description => "";
public string Help => "";
public JoinGameCommand()
{
IoCManager.InjectDependencies(this);
}
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var output = string.Join(".", args);
if (player == null)
{
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel == GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "Round has not started.");
return;
}
else if(ticker.RunLevel == GameRunLevel.InRound)
{
string ID = args[0];
var positions = ticker.GetAvailablePositions();
if(positions.GetValueOrDefault(ID, 0) == 0) //n < 0 is treated as infinite
{
var jobPrototype = _prototypeManager.Index<JobPrototype>(ID);
shell.SendText(player, $"{jobPrototype.Name} has no available slots.");
return;
}
ticker.MakeJoinGame(player, args[0].ToString());
return;
}
ticker.MakeJoinGame(player, null);
}
}
[AnyCommand]
class ToggleReadyCommand : IClientCommand
{
public string Command => "toggleready";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player == null)
{
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.ToggleReady(player, bool.Parse(args[0]));
}
}
[AdminCommand(AdminFlags.Server)]
class ToggleDisallowLateJoinCommand: IClientCommand
{
public string Command => "toggledisallowlatejoin";
public string Description => "Allows or disallows latejoining during mid-game.";
public string Help => $"Usage: {Command} <disallow>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Need exactly one argument.");
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
if (bool.TryParse(args[0], out var result))
{
ticker.ToggleDisallowLateJoin(bool.Parse(args[0]));
shell.SendText(player, result ? "Late joining has been disabled." : "Late joining has been enabled.");
}
else
{
shell.SendText(player, "Invalid argument.");
}
}
}
[AdminCommand(AdminFlags.Server)]
class SetGamePresetCommand : IClientCommand
{
public string Command => "setgamepreset";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Need exactly one argument.");
return;
}
var ticker = IoCManager.Resolve<IGameTicker>();
ticker.SetStartPreset(args[0]);
}
}
[AdminCommand(AdminFlags.Server)]
class ForcePresetCommand : IClientCommand
{
public string Command => "forcepreset";
public string Description => "Forces a specific game preset to start for the current lobby.";
public string Help => $"Usage: {Command} <preset>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var ticker = IoCManager.Resolve<IGameTicker>();
if (ticker.RunLevel != GameRunLevel.PreRoundLobby)
{
shell.SendText(player, "This can only be executed while the game is in the pre-round lobby.");
return;
}
if (args.Length != 1)
{
shell.SendText(player, "Need exactly one argument.");
return;
}
var name = args[0];
if (!ticker.TryGetPreset(name, out var type))
{
shell.SendText(player, $"No preset exists with name {name}.");
return;
}
ticker.SetStartPreset(type, true);
shell.SendText(player, $"Forced the game to start with preset {name}.");
}
}
[AdminCommand(AdminFlags.Server | AdminFlags.Mapping)]
class MappingCommand : IClientCommand
{
public string Command => "mapping";
public string Description => "Creates and teleports you to a new uninitialized map for mapping.";
public string Help => $"Usage: {Command} <mapname> / {Command} <id> <mapname>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (player == null)
{
shell.SendText(player, "Only players can use this command");
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
int mapId;
string mapName;
switch (args.Length)
{
case 1:
if (player.AttachedEntity == null)
{
shell.SendText(player, "The map name argument cannot be omitted if you have no entity.");
return;
}
mapId = (int) mapManager.NextMapId();
mapName = args[0];
break;
case 2:
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
mapId = id;
mapName = args[1];
break;
default:
shell.SendText(player, Help);
return;
}
shell.ExecuteCommand(player, $"addmap {mapId} false");
shell.ExecuteCommand(player, $"loadbp {mapId} \"{CommandParsing.Escape(mapName)}\"");
shell.ExecuteCommand(player, "aghost");
shell.ExecuteCommand(player, $"tp 0 0 {mapId}");
var newGridId = mapManager.GetAllGrids().Max(g => (int) g.Index);
shell.SendText(player, $"Created unloaded map from file {mapName} with id {mapId}. Use \"savebp {newGridId} foo.yml\" to save the new grid as a map.");
}
}
[AdminCommand(AdminFlags.Mapping)]
class TileWallsCommand : IClientCommand
{
// ReSharper disable once StringLiteralTypo
public string Command => "tilewalls";
public string Description => "Puts an underplating tile below every wall on a grid.";
public string Help => $"Usage: {Command} <gridId> | {Command}";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
GridId gridId;
switch (args.Length)
{
case 0:
if (player?.AttachedEntity == null)
{
shell.SendText((IPlayerSession) null, "Only a player can run this command.");
return;
}
gridId = player.AttachedEntity.Transform.GridID;
break;
case 1:
if (!int.TryParse(args[0], out var id))
{
shell.SendText(player, $"{args[0]} is not a valid integer.");
return;
}
gridId = new GridId(id);
break;
default:
shell.SendText(player, Help);
return;
}
var mapManager = IoCManager.Resolve<IMapManager>();
if (!mapManager.TryGetGrid(gridId, out var grid))
{
shell.SendText(player, $"No grid exists with id {gridId}");
return;
}
var entityManager = IoCManager.Resolve<IEntityManager>();
if (!entityManager.TryGetEntity(grid.GridEntityId, out var gridEntity))
{
shell.SendText(player, $"Grid {gridId} doesn't have an associated grid entity.");
return;
}
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
var underplating = tileDefinitionManager["underplating"];
var underplatingTile = new Tile(underplating.TileId);
var changed = 0;
foreach (var childUid in gridEntity.Transform.ChildEntityUids)
{
if (!entityManager.TryGetEntity(childUid, out var childEntity))
{
continue;
}
var prototype = childEntity.Prototype;
while (true)
{
if (prototype?.Parent == null)
{
break;
}
prototype = prototype.Parent;
}
if (prototype?.ID != "base_wall")
{
continue;
}
if (!childEntity.TryGetComponent(out SnapGridComponent snapGrid))
{
continue;
}
var tile = grid.GetTileRef(childEntity.Transform.Coordinates);
var tileDef = (ContentTileDefinition) tileDefinitionManager[tile.Tile.TypeId];
if (tileDef.Name == "underplating")
{
continue;
}
grid.SetTile(childEntity.Transform.Coordinates, underplatingTile);
changed++;
}
shell.SendText(player, $"Changed {changed} tiles.");
}
}
}

View File

@@ -1,170 +0,0 @@
using System.Text;
using Content.Server.Administration;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.Mobs.Roles;
using Content.Server.Players;
using Content.Shared.Administration;
using Content.Shared.Roles;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
namespace Content.Server.Mobs
{
[AdminCommand(AdminFlags.Admin)]
public class MindInfoCommand : IClientCommand
{
public string Command => "mindinfo";
public string Description => "Lists info for the mind of a specific player.";
public string Help => "mindinfo <session ID>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Expected exactly 1 argument.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetSessionByUsername(args[0], out var data))
{
var mind = data.ContentData().Mind;
var builder = new StringBuilder();
builder.AppendFormat("player: {0}, mob: {1}\nroles: ", mind.UserId, mind.OwnedMob?.Owner?.Uid);
foreach (var role in mind.AllRoles)
{
builder.AppendFormat("{0} ", role.Name);
}
shell.SendText(player, builder.ToString());
}
else
{
shell.SendText(player, "Can't find that mind");
}
}
}
[AdminCommand(AdminFlags.Fun)]
public class AddRoleCommand : IClientCommand
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public string Command => "addrole";
public string Description => "Adds a role to a player's mind.";
public string Help => "addrole <session ID> <Role Type>\nThat role type is the actual C# type name.";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
var mind = data.ContentData().Mind;
var role = new Job(mind, _prototypeManager.Index<JobPrototype>(args[1]));
mind.AddRole(role);
}
else
{
shell.SendText(player, "Can't find that mind");
}
}
}
[AdminCommand(AdminFlags.Fun)]
public class RemoveRoleCommand : IClientCommand
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public string Command => "rmrole";
public string Description => "Removes a role from a player's mind.";
public string Help => "rmrole <session ID> <Role Type>\nThat role type is the actual C# type name.";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
var mind = data.ContentData().Mind;
var role = new Job(mind, _prototypeManager.Index<JobPrototype>(args[1]));
mind.RemoveRole(role);
}
else
{
shell.SendText(player, "Can't find that mind");
}
}
}
[AdminCommand(AdminFlags.Debug)]
public class AddOverlayCommand : IClientCommand
{
public string Command => "addoverlay";
public string Description => "Adds an overlay by its ID";
public string Help => "addoverlay <id>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Expected 1 argument.");
return;
}
if (player?.AttachedEntity != null)
{
if (player.AttachedEntity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent))
{
overlayEffectsComponent.AddOverlay(args[0]);
}
}
}
}
[AdminCommand(AdminFlags.Debug)]
public class RemoveOverlayCommand : IClientCommand
{
public string Command => "rmoverlay";
public string Description => "Removes an overlay by its ID";
public string Help => "rmoverlay <id>";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
if (args.Length != 1)
{
shell.SendText(player, "Expected 1 argument.");
return;
}
if (player?.AttachedEntity != null)
{
if (player.AttachedEntity.TryGetComponent(out ServerOverlayEffectsComponent overlayEffectsComponent))
{
overlayEffectsComponent.RemoveOverlay(args[0]);
}
}
}
}
}

View File

@@ -1,139 +0,0 @@
#nullable enable
using System.Linq;
using Content.Server.Administration;
using Content.Server.Players;
using Content.Shared.Administration;
using Robust.Server.Interfaces.Console;
using Robust.Server.Interfaces.Player;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
namespace Content.Server.Objectives
{
[AdminCommand(AdminFlags.Admin)]
public class AddObjectiveCommand : IClientCommand
{
public string Command => "addobjective";
public string Description => "Adds an objective to the player's mind.";
public string Help => "addobjective <username> <objectiveID>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (!mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
shell.SendText(player, "Can't find the playerdata.");
return;
}
var mind = data.ContentData()?.Mind;
if (mind == null)
{
shell.SendText(player, "Can't find the mind.");
return;
}
if (!IoCManager.Resolve<IPrototypeManager>()
.TryIndex<ObjectivePrototype>(args[1], out var objectivePrototype))
{
shell.SendText(player, $"Can't find matching ObjectivePrototype {objectivePrototype}");
return;
}
if (!mind.TryAddObjective(objectivePrototype))
{
shell.SendText(player, "Objective requirements dont allow that objective to be added.");
}
}
}
[AdminCommand(AdminFlags.Admin)]
public class ListObjectivesCommand : IClientCommand
{
public string Command => "lsobjectives";
public string Description => "Lists all objectives in a players mind.";
public string Help => "lsobjectives [<username>]";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
IPlayerData? data;
if (args.Length == 0 && player != null)
{
data = player.Data;
}
else if (player == null || !IoCManager.Resolve<IPlayerManager>().TryGetPlayerDataByUsername(args[0], out data))
{
shell.SendText(player, "Can't find the playerdata.");
return;
}
var mind = data.ContentData()?.Mind;
if (mind == null)
{
shell.SendText(player, "Can't find the mind.");
return;
}
shell.SendText(player, $"Objectives for player {data.UserId}:");
var objectives = mind.AllObjectives.ToList();
if (objectives.Count == 0)
{
shell.SendText(player, "None.");
}
for (var i = 0; i < objectives.Count; i++)
{
shell.SendText(player, $"- [{i}] {objectives[i]}");
}
}
}
[AdminCommand(AdminFlags.Admin)]
public class RemoveObjectiveCommand : IClientCommand
{
public string Command => "rmobjective";
public string Description => "Removes an objective from the player's mind.";
public string Help => "rmobjective <username> <index>";
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
{
if (args.Length != 2)
{
shell.SendText(player, "Expected exactly 2 arguments.");
return;
}
var mgr = IoCManager.Resolve<IPlayerManager>();
if (mgr.TryGetPlayerDataByUsername(args[0], out var data))
{
var mind = data.ContentData()?.Mind;
if (mind == null)
{
shell.SendText(player, "Can't find the mind.");
return;
}
if (int.TryParse(args[1], out var i))
{
shell.SendText(player,
mind.TryRemoveObjective(i)
? "Objective successfully removed!"
: "Objective removing failed. Maybe the index is out of bounds? Check lsobjectives!");
}
else
{
shell.SendText(player, $"Invalid index {args[1]}!");
}
}
else
{
shell.SendText(player, "Can't find the playerdata.");
}
}
}
}

View File

@@ -72,24 +72,5 @@ namespace Content.Server
_netManager.ServerSendMessage(netMessage, actor.playerSession.ConnectedClient);
}
[AdminCommand(AdminFlags.Debug)]
public class PopupMsgCommand : IClientCommand
{
public string Command => "srvpopupmsg";
public string Description => "";
public string Help => "";
public void Execute(IConsoleShell shell, IPlayerSession player, string[] args)
{
var entityMgr = IoCManager.Resolve<IEntityManager>();
var source = EntityUid.Parse(args[0]);
var viewer = EntityUid.Parse(args[1]);
var msg = args[2];
entityMgr.GetEntity(source).PopupMessage(entityMgr.GetEntity(viewer), msg);
}
}
}
}