Device link visualizer (#11054)
* shuffles devicelist to shared, adds an overlay for devicelist * adds space property to overlay * moves networkconfigurator to shared, makes devicelistsystem clientside check activedevicelist * dirties components upon change, adds networkedcomponent to sharednetworkconfigurator * state handlers for networked components * whoops * lots of shuffling, renaming, and access changes * randomizes color for every new entity added to the overlay * adds a client-side action to clear all network overlays if they're active * clones action (oops) * localization, adds a command for clearing network link overlays (in case the action disappears) * moves the entity manager up into the bui fields * makes that a dependency * attempts to just directly get the color from the dict when drawing, now * fixes up a few comments * adds dirty on init to devicelistcomponent * hacky solution related to mapping with a networkconfigurator * more stricter bound on that hacky solution * just checks if the life stage is initialized instead of if the entity was initialized * moves getalldevices to shared * readds linq import * tries to ensure that the show button is toggled on if the device we're trying to configure is currently being tracked by the overlay * some reorganization
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
namespace Content.Client.NetworkConfigurator;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is used for...
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class NetworkConfiguratorActiveLinkOverlayComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The entities linked to this network configurator.
|
||||||
|
/// This could just... couldn't this just be grabbed
|
||||||
|
/// if DeviceList was shared?
|
||||||
|
/// </summary>
|
||||||
|
public HashSet<EntityUid> Devices = new();
|
||||||
|
}
|
||||||
@@ -1,16 +1,24 @@
|
|||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
|
||||||
namespace Content.Client.NetworkConfigurator;
|
namespace Content.Client.NetworkConfigurator;
|
||||||
|
|
||||||
public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
|
public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
private NetworkConfiguratorListMenu? _listMenu;
|
private NetworkConfiguratorListMenu? _listMenu;
|
||||||
private NetworkConfiguratorConfigurationMenu? _configurationMenu;
|
private NetworkConfiguratorConfigurationMenu? _configurationMenu;
|
||||||
|
|
||||||
|
private NetworkConfiguratorSystem _netConfig;
|
||||||
|
private DeviceListSystem _deviceList;
|
||||||
|
|
||||||
public NetworkConfiguratorBoundUserInterface(ClientUserInterfaceComponent owner, Enum uiKey) : base(owner, uiKey)
|
public NetworkConfiguratorBoundUserInterface(ClientUserInterfaceComponent owner, Enum uiKey) : base(owner, uiKey)
|
||||||
{
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
_netConfig = _entityManager.System<NetworkConfiguratorSystem>();
|
||||||
|
_deviceList = _entityManager.System<DeviceListSystem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnRemoveButtonPressed(string address)
|
public void OnRemoveButtonPressed(string address)
|
||||||
@@ -38,12 +46,31 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
|
|||||||
//_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit);
|
//_configurationMenu.Edit.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Edit);
|
||||||
_configurationMenu.Clear.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Clear);
|
_configurationMenu.Clear.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Clear);
|
||||||
_configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy);
|
_configurationMenu.Copy.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Copy);
|
||||||
_configurationMenu.Show.OnPressed += _ => OnConfigButtonPressed(NetworkConfiguratorButtonKey.Show);
|
_configurationMenu.Show.OnPressed += OnShowPressed;
|
||||||
|
_configurationMenu.Show.Pressed = _netConfig.ConfiguredListIsTracked(Owner.Owner);
|
||||||
_configurationMenu.OpenCentered();
|
_configurationMenu.OpenCentered();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnShowPressed(BaseButton.ButtonEventArgs args)
|
||||||
|
{
|
||||||
|
if (!args.Button.Pressed)
|
||||||
|
{
|
||||||
|
_netConfig.ToggleVisualization(Owner.Owner, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_entityManager.GetComponent<MetaDataComponent>(Owner.Owner).EntityLifeStage == EntityLifeStage.Initialized)
|
||||||
|
{
|
||||||
|
// We're in mapping mode. Do something hacky.
|
||||||
|
SendMessage(new ManualDeviceListSyncMessage(null, null));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_netConfig.ToggleVisualization(Owner.Owner, true);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UpdateState(BoundUserInterfaceState state)
|
protected override void UpdateState(BoundUserInterfaceState state)
|
||||||
{
|
{
|
||||||
base.UpdateState(state);
|
base.UpdateState(state);
|
||||||
@@ -52,6 +79,25 @@ public sealed class NetworkConfiguratorBoundUserInterface : BoundUserInterface
|
|||||||
_listMenu?.UpdateState(castState);
|
_listMenu?.UpdateState(castState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
|
||||||
|
{
|
||||||
|
base.ReceiveMessage(message);
|
||||||
|
|
||||||
|
if (_configurationMenu == null
|
||||||
|
|| _entityManager.GetComponent<MetaDataComponent>(Owner.Owner).EntityLifeStage > EntityLifeStage.Initialized
|
||||||
|
|| message is not ManualDeviceListSyncMessage cast
|
||||||
|
|| cast.Device == null
|
||||||
|
|| cast.Devices == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_netConfig.SetActiveDeviceList(Owner.Owner, cast.Device.Value);
|
||||||
|
_deviceList.UpdateDeviceList(cast.Device.Value, cast.Devices);
|
||||||
|
_netConfig.ToggleVisualization(Owner.Owner, true);
|
||||||
|
_configurationMenu.Show.Pressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8 0 8 8">
|
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="8 0 8 8">
|
||||||
<Button Name="Copy" Text="Copy" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-copy'}" HorizontalExpand="True" StyleClasses="OpenRight"/>
|
<Button Name="Copy" Text="Copy" Access="Public" ToolTip="{Loc 'network-configurator-tooltip-copy'}" HorizontalExpand="True" StyleClasses="OpenRight"/>
|
||||||
<Button Name="Show" Text="Show" Access="Public" Disabled="True" ToolTip="{Loc 'network-configurator-tooltip-show'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
<Button Name="Show" Text="Show" Access="Public" ToggleMode="True" ToolTip="{Loc 'network-configurator-tooltip-show'}" HorizontalExpand="True" StyleClasses="ButtonSquare"/>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</ui:FancyWindow>
|
</ui:FancyWindow>
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using Content.Shared.DeviceNetwork;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Shared.Enums;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.NetworkConfigurator;
|
||||||
|
|
||||||
|
public sealed class NetworkConfiguratorLinkOverlay : Overlay
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
private readonly DeviceListSystem _deviceListSystem;
|
||||||
|
|
||||||
|
private Dictionary<EntityUid, Color> _colors = new();
|
||||||
|
|
||||||
|
public override OverlaySpace Space => OverlaySpace.WorldSpace;
|
||||||
|
|
||||||
|
public NetworkConfiguratorLinkOverlay()
|
||||||
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
|
||||||
|
_deviceListSystem = _entityManager.System<DeviceListSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearEntity(EntityUid uid)
|
||||||
|
{
|
||||||
|
_colors.Remove(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(in OverlayDrawArgs args)
|
||||||
|
{
|
||||||
|
foreach (var tracker in _entityManager.EntityQuery<NetworkConfiguratorActiveLinkOverlayComponent>())
|
||||||
|
{
|
||||||
|
if (_entityManager.Deleted(tracker.Owner) || !_entityManager.TryGetComponent(tracker.Owner, out DeviceListComponent? deviceList))
|
||||||
|
{
|
||||||
|
_entityManager.RemoveComponentDeferred<NetworkConfiguratorActiveLinkOverlayComponent>(tracker.Owner);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_colors.TryGetValue(tracker.Owner, out var color))
|
||||||
|
{
|
||||||
|
color = new Color(
|
||||||
|
_random.Next(0, 255),
|
||||||
|
_random.Next(0, 255),
|
||||||
|
_random.Next(0, 255));
|
||||||
|
_colors.Add(tracker.Owner, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceTransform = _entityManager.GetComponent<TransformComponent>(tracker.Owner);
|
||||||
|
|
||||||
|
foreach (var device in _deviceListSystem.GetAllDevices(tracker.Owner, deviceList))
|
||||||
|
{
|
||||||
|
if (_entityManager.Deleted(device))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var linkTransform = _entityManager.GetComponent<TransformComponent>(device);
|
||||||
|
|
||||||
|
args.WorldHandle.DrawLine(sourceTransform.WorldPosition, linkTransform.WorldPosition, _colors[tracker.Owner]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Shared.DeviceNetwork;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
|
||||||
|
namespace Content.Client.NetworkConfigurator;
|
||||||
|
|
||||||
|
public sealed class DeviceListSystem : SharedDeviceListSystem
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Client.Actions;
|
||||||
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Actions.ActionTypes;
|
||||||
|
using Content.Shared.DeviceNetwork;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
using Robust.Shared.Console;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Client.NetworkConfigurator;
|
||||||
|
|
||||||
|
public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
|
[Dependency] private readonly IOverlayManager _overlay = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||||
|
|
||||||
|
private const string Action = "ClearNetworkLinkOverlays";
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<ClearAllOverlaysEvent>(_ => ClearAllOverlays());
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ConfiguredListIsTracked(EntityUid uid, NetworkConfiguratorComponent? component = null)
|
||||||
|
{
|
||||||
|
return Resolve(uid, ref component)
|
||||||
|
&& component.ActiveDeviceList != null
|
||||||
|
&& HasComp<NetworkConfiguratorActiveLinkOverlayComponent>(component.ActiveDeviceList.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles a device list's (tied to this network configurator) connection visualisation on and off.
|
||||||
|
/// </summary>
|
||||||
|
public void ToggleVisualization(EntityUid uid, bool toggle, NetworkConfiguratorComponent? component = null)
|
||||||
|
{
|
||||||
|
if (_playerManager.LocalPlayer == null
|
||||||
|
|| _playerManager.LocalPlayer.ControlledEntity == null
|
||||||
|
|| !Resolve(uid, ref component)
|
||||||
|
|| component.ActiveDeviceList == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!toggle)
|
||||||
|
{
|
||||||
|
if (_overlay.HasOverlay<NetworkConfiguratorLinkOverlay>())
|
||||||
|
{
|
||||||
|
_overlay.GetOverlay<NetworkConfiguratorLinkOverlay>().ClearEntity(component.ActiveDeviceList.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemComp<NetworkConfiguratorActiveLinkOverlayComponent>(component.ActiveDeviceList.Value);
|
||||||
|
if (!EntityQuery<NetworkConfiguratorActiveLinkOverlayComponent>().Any())
|
||||||
|
{
|
||||||
|
_overlay.RemoveOverlay<NetworkConfiguratorLinkOverlay>();
|
||||||
|
_actions.RemoveAction(_playerManager.LocalPlayer.ControlledEntity.Value, _prototypeManager.Index<InstantActionPrototype>(Action));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_overlay.HasOverlay<NetworkConfiguratorLinkOverlay>())
|
||||||
|
{
|
||||||
|
_overlay.AddOverlay(new NetworkConfiguratorLinkOverlay());
|
||||||
|
_actions.AddAction(_playerManager.LocalPlayer.ControlledEntity.Value, new InstantAction(_prototypeManager.Index<InstantActionPrototype>(Action)), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureComp<NetworkConfiguratorActiveLinkOverlayComponent>(component.ActiveDeviceList.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearAllOverlays()
|
||||||
|
{
|
||||||
|
if (!_overlay.HasOverlay<NetworkConfiguratorLinkOverlay>())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var tracker in EntityQuery<NetworkConfiguratorActiveLinkOverlayComponent>())
|
||||||
|
{
|
||||||
|
RemCompDeferred<NetworkConfiguratorActiveLinkOverlayComponent>(tracker.Owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
_overlay.RemoveOverlay<NetworkConfiguratorLinkOverlay>();
|
||||||
|
|
||||||
|
if (_playerManager.LocalPlayer?.ControlledEntity != null)
|
||||||
|
{
|
||||||
|
_actions.RemoveAction(_playerManager.LocalPlayer.ControlledEntity.Value, _prototypeManager.Index<InstantActionPrototype>(Action));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hacky solution related to mapping
|
||||||
|
public void SetActiveDeviceList(EntityUid tool, EntityUid list, NetworkConfiguratorComponent? component = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(tool, ref component))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
component.ActiveDeviceList = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ClearAllNetworkLinkOverlays : IConsoleCommand
|
||||||
|
{
|
||||||
|
public string Command => "clearnetworklinkoverlays";
|
||||||
|
public string Description => "Clear all network link overlays.";
|
||||||
|
public string Help => Command;
|
||||||
|
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||||
|
{
|
||||||
|
IoCManager.Resolve<IEntityManager>().System<NetworkConfiguratorSystem>().ClearAllOverlays();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ using Content.Shared.Atmos;
|
|||||||
using Content.Shared.Atmos.Monitor;
|
using Content.Shared.Atmos.Monitor;
|
||||||
using Content.Shared.Atmos.Monitor.Components;
|
using Content.Shared.Atmos.Monitor.Components;
|
||||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||||
|
using Content.Shared.DeviceNetwork;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Content.Server.Power.Components;
|
|||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Shared.AlertLevel;
|
using Content.Shared.AlertLevel;
|
||||||
using Content.Shared.Atmos.Monitor;
|
using Content.Shared.Atmos.Monitor;
|
||||||
|
using Content.Shared.DeviceNetwork;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.DeviceNetwork.Components;
|
using Content.Server.DeviceNetwork.Components;
|
||||||
|
using Content.Shared.DeviceNetwork;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace Content.Server.DeviceNetwork.Systems;
|
namespace Content.Server.DeviceNetwork.Systems;
|
||||||
|
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class DeviceListSystem : EntitySystem
|
public sealed class DeviceListSystem : SharedDeviceListSystem
|
||||||
{
|
{
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -15,23 +16,6 @@ public sealed class DeviceListSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<DeviceListComponent, BeforePacketSentEvent>(OnBeforePacketSent);
|
SubscribeLocalEvent<DeviceListComponent, BeforePacketSentEvent>(OnBeforePacketSent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Replaces or merges the current device list with the given one
|
|
||||||
/// </summary>
|
|
||||||
public void UpdateDeviceList(EntityUid uid, IEnumerable<EntityUid> devices, bool merge = false, DeviceListComponent? deviceList = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref deviceList))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!merge)
|
|
||||||
deviceList.Devices.Clear();
|
|
||||||
|
|
||||||
var devicesList = devices.ToList();
|
|
||||||
deviceList.Devices.UnionWith(devicesList);
|
|
||||||
|
|
||||||
RaiseLocalEvent(uid, new DeviceListUpdateEvent(devicesList));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the given device list as a dictionary
|
/// Gets the given device list as a dictionary
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -54,16 +38,6 @@ public sealed class DeviceListSystem : EntitySystem
|
|||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggles the given device lists connection visualisation on and off.
|
|
||||||
/// TODO: Implement an overlay that draws a line between the given entity and the entities in the device list
|
|
||||||
/// </summary>
|
|
||||||
public void ToggleVisualization(EntityUid uid, bool ensureOff = false, DeviceListComponent? deviceList = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref deviceList))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters the broadcasts recipient list against the device list as either an allow or deny list depending on the components IsAllowList field
|
/// Filters the broadcasts recipient list against the device list as either an allow or deny list depending on the components IsAllowList field
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -95,13 +69,3 @@ public sealed class DeviceListSystem : EntitySystem
|
|||||||
args.Cancel();
|
args.Cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class DeviceListUpdateEvent : EntityEventArgs
|
|
||||||
{
|
|
||||||
public DeviceListUpdateEvent(List<EntityUid> devices)
|
|
||||||
{
|
|
||||||
Devices = devices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EntityUid> Devices { get; }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.DeviceNetwork.Components;
|
using System.Linq;
|
||||||
|
using Content.Server.DeviceNetwork.Components;
|
||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
using Content.Shared.Access.Components;
|
using Content.Shared.Access.Components;
|
||||||
using Content.Shared.Access.Systems;
|
using Content.Shared.Access.Systems;
|
||||||
@@ -11,13 +12,14 @@ using Content.Shared.Popups;
|
|||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Server.Player;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
namespace Content.Server.DeviceNetwork.Systems;
|
namespace Content.Server.DeviceNetwork.Systems;
|
||||||
|
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class NetworkConfiguratorSystem : EntitySystem
|
public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly DeviceListSystem _deviceListSystem = default!;
|
[Dependency] private readonly DeviceListSystem _deviceListSystem = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
@@ -44,6 +46,7 @@ public sealed class NetworkConfiguratorSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<NetworkConfiguratorComponent, NetworkConfiguratorRemoveDeviceMessage>(OnRemoveDevice);
|
SubscribeLocalEvent<NetworkConfiguratorComponent, NetworkConfiguratorRemoveDeviceMessage>(OnRemoveDevice);
|
||||||
SubscribeLocalEvent<NetworkConfiguratorComponent, NetworkConfiguratorClearDevicesMessage>(OnClearDevice);
|
SubscribeLocalEvent<NetworkConfiguratorComponent, NetworkConfiguratorClearDevicesMessage>(OnClearDevice);
|
||||||
SubscribeLocalEvent<NetworkConfiguratorComponent, NetworkConfiguratorButtonPressedMessage>(OnConfigButtonPressed);
|
SubscribeLocalEvent<NetworkConfiguratorComponent, NetworkConfiguratorButtonPressedMessage>(OnConfigButtonPressed);
|
||||||
|
SubscribeLocalEvent<NetworkConfiguratorComponent, ManualDeviceListSyncMessage>(ManualDeviceListSync);
|
||||||
|
|
||||||
SubscribeLocalEvent<DeviceListComponent, ComponentRemove>(OnComponentRemoved);
|
SubscribeLocalEvent<DeviceListComponent, ComponentRemove>(OnComponentRemoved);
|
||||||
}
|
}
|
||||||
@@ -217,6 +220,7 @@ public sealed class NetworkConfiguratorSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
configurator.ActiveDeviceList = targetUid;
|
configurator.ActiveDeviceList = targetUid;
|
||||||
|
Dirty(configurator);
|
||||||
_uiSystem.GetUiOrNull(configurator.Owner, NetworkConfiguratorUiKey.Configure)?.Open(actor.PlayerSession);
|
_uiSystem.GetUiOrNull(configurator.Owner, NetworkConfiguratorUiKey.Configure)?.Open(actor.PlayerSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,10 +303,25 @@ public sealed class NetworkConfiguratorSystem : EntitySystem
|
|||||||
UpdateUiState(uid, component);
|
UpdateUiState(uid, component);
|
||||||
break;
|
break;
|
||||||
case NetworkConfiguratorButtonKey.Show:
|
case NetworkConfiguratorButtonKey.Show:
|
||||||
_deviceListSystem.ToggleVisualization(component.ActiveDeviceList.Value);
|
// This should be done client-side.
|
||||||
|
// _deviceListSystem.ToggleVisualization(component.ActiveDeviceList.Value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hacky solution related to mapping
|
||||||
|
private void ManualDeviceListSync(EntityUid uid, NetworkConfiguratorComponent comp,
|
||||||
|
ManualDeviceListSyncMessage args)
|
||||||
|
{
|
||||||
|
if (comp.ActiveDeviceList == null || args.Session is not IPlayerSession player)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var devices = _deviceListSystem.GetAllDevices(comp.ActiveDeviceList.Value).ToHashSet();
|
||||||
|
|
||||||
|
_uiSystem.TrySendUiMessage(uid, NetworkConfiguratorUiKey.Configure, new ManualDeviceListSyncMessage(comp.ActiveDeviceList.Value, devices), player);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
using Content.Server.DeviceNetwork.Systems;
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Server.DeviceNetwork.Components;
|
namespace Content.Shared.DeviceNetwork;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[Access(typeof(DeviceListSystem))]
|
[NetworkedComponent]
|
||||||
|
[Access(typeof(SharedDeviceListSystem))]
|
||||||
public sealed class DeviceListComponent : Component
|
public sealed class DeviceListComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -26,3 +28,18 @@ public sealed class DeviceListComponent : Component
|
|||||||
[DataField("handleIncoming")]
|
[DataField("handleIncoming")]
|
||||||
public bool HandleIncomingPackets = false;
|
public bool HandleIncomingPackets = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class DeviceListComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public readonly HashSet<EntityUid> Devices;
|
||||||
|
public readonly bool IsAllowList;
|
||||||
|
public readonly bool HandleIncomingPackets;
|
||||||
|
|
||||||
|
public DeviceListComponentState(HashSet<EntityUid> devices, bool isAllowList, bool handleIncomingPackets)
|
||||||
|
{
|
||||||
|
Devices = devices;
|
||||||
|
IsAllowList = isAllowList;
|
||||||
|
HandleIncomingPackets = handleIncomingPackets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,37 @@
|
|||||||
using Content.Server.DeviceNetwork.Systems;
|
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Server.DeviceNetwork.Components;
|
namespace Content.Shared.DeviceNetwork;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[Access(typeof(NetworkConfiguratorSystem))]
|
[NetworkedComponent]
|
||||||
|
[Access(typeof(SharedNetworkConfiguratorSystem))]
|
||||||
public sealed class NetworkConfiguratorComponent : Component
|
public sealed class NetworkConfiguratorComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The list of devices stored in the configurator-
|
|
||||||
/// </summary>
|
|
||||||
[DataField("devices")]
|
|
||||||
public Dictionary<string, EntityUid> Devices = new();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entity containing a <see cref="DeviceListComponent"/> this configurator is currently interacting with
|
/// The entity containing a <see cref="DeviceListComponent"/> this configurator is currently interacting with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("activeDeviceList")]
|
[DataField("activeDeviceList")]
|
||||||
public EntityUid? ActiveDeviceList = null;
|
public EntityUid? ActiveDeviceList = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of devices stored in the configurator-
|
||||||
|
/// </summary>
|
||||||
|
[DataField("devices")]
|
||||||
|
public Dictionary<string, EntityUid> Devices = new();
|
||||||
|
|
||||||
[DataField("soundNoAccess")]
|
[DataField("soundNoAccess")]
|
||||||
public SoundSpecifier SoundNoAccess = new SoundPathSpecifier("/Audio/Machines/custom_deny.ogg");
|
public SoundSpecifier SoundNoAccess = new SoundPathSpecifier("/Audio/Machines/custom_deny.ogg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class NetworkConfiguratorComponentState : ComponentState
|
||||||
|
{
|
||||||
|
public readonly EntityUid? ActiveDeviceList;
|
||||||
|
|
||||||
|
public NetworkConfiguratorComponentState(EntityUid? activeDeviceList)
|
||||||
|
{
|
||||||
|
ActiveDeviceList = activeDeviceList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.DeviceNetwork;
|
||||||
|
|
||||||
|
public abstract class SharedDeviceListSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<DeviceListComponent, ComponentGetState>(GetDeviceListState);
|
||||||
|
SubscribeLocalEvent<DeviceListComponent, ComponentHandleState>(HandleDeviceListState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the device list stored on this entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid">The entity to update.</param>
|
||||||
|
/// <param name="devices">The devices to store.</param>
|
||||||
|
/// <param name="merge">Whether to merge or replace the devices stored.</param>
|
||||||
|
/// <param name="deviceList">Device list component</param>
|
||||||
|
public void UpdateDeviceList(EntityUid uid, IEnumerable<EntityUid> devices, bool merge = false, DeviceListComponent? deviceList = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref deviceList))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!merge)
|
||||||
|
deviceList.Devices.Clear();
|
||||||
|
|
||||||
|
var devicesList = devices.ToList();
|
||||||
|
deviceList.Devices.UnionWith(devicesList);
|
||||||
|
|
||||||
|
RaiseLocalEvent(uid, new DeviceListUpdateEvent(devicesList));
|
||||||
|
|
||||||
|
Dirty(deviceList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<EntityUid> GetAllDevices(EntityUid uid, DeviceListComponent? component = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref component))
|
||||||
|
{
|
||||||
|
return new EntityUid[] { };
|
||||||
|
}
|
||||||
|
return component.Devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetDeviceListState(EntityUid uid, DeviceListComponent comp, ref ComponentGetState args)
|
||||||
|
{
|
||||||
|
args.State = new DeviceListComponentState(comp.Devices, comp.IsAllowList, comp.HandleIncomingPackets);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDeviceListState(EntityUid uid, DeviceListComponent comp, ref ComponentHandleState args)
|
||||||
|
{
|
||||||
|
if (args.Current is not DeviceListComponentState state)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
comp.Devices = state.Devices;
|
||||||
|
comp.HandleIncomingPackets = state.HandleIncomingPackets;
|
||||||
|
comp.IsAllowList = state.IsAllowList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class DeviceListUpdateEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public DeviceListUpdateEvent(List<EntityUid> devices)
|
||||||
|
{
|
||||||
|
Devices = devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EntityUid> Devices { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using Content.Shared.Actions;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.DeviceNetwork;
|
||||||
|
|
||||||
|
public abstract class SharedNetworkConfiguratorSystem : EntitySystem
|
||||||
|
{
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<NetworkConfiguratorComponent, ComponentGetState>(GetNetworkConfiguratorState);
|
||||||
|
SubscribeLocalEvent<NetworkConfiguratorComponent, ComponentHandleState>(HandleNetworkConfiguratorState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void GetNetworkConfiguratorState(EntityUid uid, NetworkConfiguratorComponent comp,
|
||||||
|
ref ComponentGetState args)
|
||||||
|
{
|
||||||
|
args.State = new NetworkConfiguratorComponentState(comp.ActiveDeviceList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleNetworkConfiguratorState(EntityUid uid, NetworkConfiguratorComponent comp,
|
||||||
|
ref ComponentHandleState args)
|
||||||
|
{
|
||||||
|
if (args.Current is not NetworkConfiguratorComponentState state)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
comp.ActiveDeviceList = state.ActiveDeviceList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class ManualDeviceListSyncMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public ManualDeviceListSyncMessage(EntityUid? device, HashSet<EntityUid>? devices)
|
||||||
|
{
|
||||||
|
Device = device;
|
||||||
|
Devices = devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityUid? Device { get; }
|
||||||
|
public HashSet<EntityUid>? Devices { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ClearAllOverlaysEvent : InstantActionEvent
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -12,6 +12,8 @@ network-configurator-configure = Configure
|
|||||||
# ui
|
# ui
|
||||||
network-configurator-ui-clear-button = Clear
|
network-configurator-ui-clear-button = Clear
|
||||||
network-configurator-ui-count-label = {$count} Devices
|
network-configurator-ui-count-label = {$count} Devices
|
||||||
|
network-configurator-clear-network-link-overlays = Clear network link overlays
|
||||||
|
network-configurator-clear-network-link-overlays-desc = Clear network link overlays.
|
||||||
|
|
||||||
# tooltips
|
# tooltips
|
||||||
network-configurator-tooltip-set = Sets targets device list
|
network-configurator-tooltip-set = Sets targets device list
|
||||||
|
|||||||
@@ -71,6 +71,13 @@
|
|||||||
iconOn: Objects/Weapons/Melee/shields.rsi/teleriot-on.png
|
iconOn: Objects/Weapons/Melee/shields.rsi/teleriot-on.png
|
||||||
event: !type:ToggleActionEvent
|
event: !type:ToggleActionEvent
|
||||||
|
|
||||||
|
- type: instantAction
|
||||||
|
id: ClearNetworkLinkOverlays
|
||||||
|
name: network-configurator-clear-network-link-overlays
|
||||||
|
description: network-configurator-clear-network-link-overlays-desc
|
||||||
|
icon: Objects/Tools/multitool.rsi/icon.png
|
||||||
|
event: !type:ClearAllOverlaysEvent
|
||||||
|
|
||||||
- type: instantAction
|
- type: instantAction
|
||||||
id: AnimalLayEgg
|
id: AnimalLayEgg
|
||||||
name: action-name-lay-egg
|
name: action-name-lay-egg
|
||||||
|
|||||||
Reference in New Issue
Block a user