SUPER CAMERA(OCHKO) (#501)
* SUPER CAMERA(OCHKO) * Удобный монитор камер и портативный мониторинг для детектива. (#25) * Улучшение мониторинга камер * Портативный монитор камер для дека * чейнжлог * Revert "Удобный монитор камер и портативный мониторинг для детектива. (#25)" This reverts commit adf35bb8f6ddd6256b18841a81b330224ebff103. * Revert "Revert "Удобный монитор камер и портативный мониторинг для детектива. (#25)"" This reverts commit bd30fe45046b7b8508e8277f8c186d03338354cd. * cleanups * its so over --------- Co-authored-by: Vigers Ray <60344369+VigersRay@users.noreply.github.com> Co-authored-by: drdth <drdtheuser@gmail.com>
This commit is contained in:
committed by
GitHub
parent
a1f562d181
commit
3ed0f2c4bb
@@ -3,7 +3,7 @@ namespace Content.Client.SurveillanceCamera;
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed partial class ActiveSurveillanceCameraMonitorVisualsComponent : Component
|
public sealed partial class ActiveSurveillanceCameraMonitorVisualsComponent : Component
|
||||||
{
|
{
|
||||||
public float TimeLeft = 10f;
|
public float TimeLeft = 0.5f;
|
||||||
|
|
||||||
public Action? OnFinish;
|
public Action? OnFinish;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,18 +14,30 @@ public sealed class SurveillanceCameraMonitorBoundUserInterface : BoundUserInter
|
|||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private EntityUid? _currentCamera;
|
private EntityUid? _currentCamera;
|
||||||
|
private readonly IEntityManager _entManager;
|
||||||
|
|
||||||
public SurveillanceCameraMonitorBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
public SurveillanceCameraMonitorBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||||
{
|
{
|
||||||
_eyeLerpingSystem = EntMan.System<EyeLerpingSystem>();
|
_eyeLerpingSystem = EntMan.System<EyeLerpingSystem>();
|
||||||
_surveillanceCameraMonitorSystem = EntMan.System<SurveillanceCameraMonitorSystem>();
|
_surveillanceCameraMonitorSystem = EntMan.System<SurveillanceCameraMonitorSystem>();
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
_entManager = IoCManager.Resolve<IEntityManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Open()
|
protected override void Open()
|
||||||
{
|
{
|
||||||
base.Open();
|
base.Open();
|
||||||
|
|
||||||
_window = new SurveillanceCameraMonitorWindow();
|
// Sunrise-start
|
||||||
|
EntityUid? gridUid = null;
|
||||||
|
|
||||||
|
if (_entManager.TryGetComponent<TransformComponent>(Owner, out var xform))
|
||||||
|
{
|
||||||
|
gridUid = xform.GridUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
_window = new SurveillanceCameraMonitorWindow(gridUid);
|
||||||
|
// Sunrise-end
|
||||||
|
|
||||||
if (State != null)
|
if (State != null)
|
||||||
{
|
{
|
||||||
@@ -35,7 +47,6 @@ public sealed class SurveillanceCameraMonitorBoundUserInterface : BoundUserInter
|
|||||||
_window.OpenCentered();
|
_window.OpenCentered();
|
||||||
|
|
||||||
_window.CameraSelected += OnCameraSelected;
|
_window.CameraSelected += OnCameraSelected;
|
||||||
_window.SubnetOpened += OnSubnetRequest;
|
|
||||||
_window.CameraRefresh += OnCameraRefresh;
|
_window.CameraRefresh += OnCameraRefresh;
|
||||||
_window.SubnetRefresh += OnSubnetRefresh;
|
_window.SubnetRefresh += OnSubnetRefresh;
|
||||||
_window.OnClose += Close;
|
_window.OnClose += Close;
|
||||||
@@ -43,14 +54,9 @@ public sealed class SurveillanceCameraMonitorBoundUserInterface : BoundUserInter
|
|||||||
_window.CameraDisconnect += OnCameraDisconnect;
|
_window.CameraDisconnect += OnCameraDisconnect;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCameraSelected(string address)
|
private void OnCameraSelected(NetEntity camera)
|
||||||
{
|
{
|
||||||
SendMessage(new SurveillanceCameraMonitorSwitchMessage(address));
|
SendMessage(new SurveillanceCameraMonitorSwitchMessage(camera));
|
||||||
}
|
|
||||||
|
|
||||||
private void OnSubnetRequest(string subnet)
|
|
||||||
{
|
|
||||||
SendMessage(new SurveillanceCameraMonitorSubnetRequestMessage(subnet));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCameraSwitchTimer()
|
private void OnCameraSwitchTimer()
|
||||||
@@ -82,9 +88,11 @@ public sealed class SurveillanceCameraMonitorBoundUserInterface : BoundUserInter
|
|||||||
|
|
||||||
var active = EntMan.GetEntity(cast.ActiveCamera);
|
var active = EntMan.GetEntity(cast.ActiveCamera);
|
||||||
|
|
||||||
|
_entManager.TryGetComponent<TransformComponent>(Owner, out var xform);
|
||||||
|
|
||||||
if (active == null)
|
if (active == null)
|
||||||
{
|
{
|
||||||
_window.UpdateState(null, cast.Subnets, cast.ActiveAddress, cast.ActiveSubnet, cast.Cameras);
|
_window.UpdateState(null, cast.ActiveAddress, cast.ActiveCamera);
|
||||||
|
|
||||||
if (_currentCamera != null)
|
if (_currentCamera != null)
|
||||||
{
|
{
|
||||||
@@ -109,9 +117,11 @@ public sealed class SurveillanceCameraMonitorBoundUserInterface : BoundUserInter
|
|||||||
|
|
||||||
if (EntMan.TryGetComponent<EyeComponent>(active, out var eye))
|
if (EntMan.TryGetComponent<EyeComponent>(active, out var eye))
|
||||||
{
|
{
|
||||||
_window.UpdateState(eye.Eye, cast.Subnets, cast.ActiveAddress, cast.ActiveSubnet, cast.Cameras);
|
_window.UpdateState(eye.Eye, cast.ActiveAddress, cast.ActiveCamera);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_window.ShowCameras(cast.Cameras, xform?.Coordinates);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
|
|||||||
@@ -1,25 +1,41 @@
|
|||||||
<DefaultWindow xmlns="https://spacestation14.io"
|
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||||
xmlns:viewport="clr-namespace:Content.Client.Viewport"
|
xmlns:viewport="clr-namespace:Content.Client.Viewport"
|
||||||
Title="{Loc 'surveillance-camera-monitor-ui-window'}">
|
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||||
<BoxContainer Orientation="Horizontal">
|
xmlns:ui="clr-namespace:Content.Client.SurveillanceCamera.UI"
|
||||||
<BoxContainer Orientation="Vertical" MinWidth="350" VerticalExpand="True">
|
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||||
<!-- lazy -->
|
Title="{Loc 'surveillance-camera-monitor-ui-window'}"
|
||||||
<OptionButton Name="SubnetSelector" />
|
Resizable="False"
|
||||||
<Button Name="SubnetRefreshButton" Text="{Loc 'surveillance-camera-monitor-ui-refresh-subnets'}" />
|
MinSize="1300 750">
|
||||||
<ScrollContainer VerticalExpand="True">
|
<BoxContainer Orientation="Vertical">
|
||||||
<ItemList Name="SubnetList" />
|
<BoxContainer Orientation="Horizontal" VerticalExpand="True" HorizontalExpand="True">
|
||||||
</ScrollContainer>
|
<ui:SurveillanceCameraNavMapControl Name="NavMap" HorizontalExpand="True" VerticalExpand="True" MinSize="600 700" VerticalAlignment="Top"/>
|
||||||
<Button Name="CameraRefreshButton" Text="{Loc 'surveillance-camera-monitor-ui-refresh-cameras'}" />
|
<customControls:VSeparator/>
|
||||||
<Button Name="CameraDisconnectButton" Text="{Loc 'surveillance-camera-monitor-ui-disconnect'}" />
|
<BoxContainer Orientation="Vertical">
|
||||||
<Label Name="CameraStatus" />
|
|
||||||
</BoxContainer>
|
|
||||||
<Control VerticalExpand="True" HorizontalExpand="True" Margin="5 5 5 5" Name="CameraViewBox">
|
<Control VerticalExpand="True" HorizontalExpand="True" Margin="5 5 5 5" Name="CameraViewBox">
|
||||||
<viewport:ScalingViewport Name="CameraView"
|
<viewport:ScalingViewport Name="CameraView"
|
||||||
VerticalExpand="True"
|
VerticalExpand="True"
|
||||||
HorizontalExpand="True"
|
HorizontalExpand="True"
|
||||||
MinSize="500 500"
|
MinSize="700 700"
|
||||||
MouseFilter="Ignore" />
|
MouseFilter="Ignore" />
|
||||||
<TextureRect VerticalExpand="True" HorizontalExpand="True" MinSize="500 500" Name="CameraViewBackground" />
|
<TextureRect VerticalExpand="True" HorizontalExpand="True" MinSize="700 700" Name="CameraViewBackground" />
|
||||||
</Control>
|
</Control>
|
||||||
|
<BoxContainer Orientation="Vertical">
|
||||||
|
<Button Name="SubnetRefreshButton" Text="{Loc 'surveillance-camera-monitor-ui-refresh-subnets'}" />
|
||||||
|
<Button Name="CameraRefreshButton" Text="{Loc 'surveillance-camera-monitor-ui-refresh-cameras'}" />
|
||||||
|
<Button Name="CameraDisconnectButton" Text="{Loc 'surveillance-camera-monitor-ui-disconnect'}" />
|
||||||
|
<Label Name="CameraStatus" />
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</DefaultWindow>
|
</BoxContainer>
|
||||||
|
</BoxContainer>
|
||||||
|
<BoxContainer Orientation="Vertical">
|
||||||
|
<PanelContainer StyleClasses="LowDivider" />
|
||||||
|
<BoxContainer Orientation="Horizontal" Margin="10 2 5 0" VerticalAlignment="Bottom">
|
||||||
|
<Label Text="{Loc 'surveillance-camera-monitor-ui-flavor-left'}" StyleClasses="WindowFooterText" />
|
||||||
|
<Label Text="{Loc 'surveillance-camera-monitor-ui-flavor-right'}" StyleClasses="WindowFooterText"
|
||||||
|
HorizontalAlignment="Right" HorizontalExpand="True" Margin="0 0 5 0" />
|
||||||
|
<TextureRect StyleClasses="NTLogoDark" Stretch="KeepAspectCentered"
|
||||||
|
VerticalAlignment="Center" HorizontalAlignment="Right" SetSize="19 19"/>
|
||||||
|
</BoxContainer>
|
||||||
|
</BoxContainer>
|
||||||
|
</BoxContainer>
|
||||||
|
</controls:FancyWindow>
|
||||||
|
|||||||
@@ -1,27 +1,28 @@
|
|||||||
using System.Linq;
|
using Content.Client.Pinpointer.UI;
|
||||||
using Content.Client.Resources;
|
using Content.Client.Resources;
|
||||||
using Content.Client.Viewport;
|
using Content.Client.Stylesheets;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Client.UserInterface.Controls;
|
||||||
using Content.Shared.SurveillanceCamera;
|
using Content.Shared.SurveillanceCamera;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.ResourceManagement;
|
using Robust.Client.ResourceManagement;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.Graphics;
|
using Robust.Shared.Graphics;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.SurveillanceCamera.UI;
|
namespace Content.Client.SurveillanceCamera.UI;
|
||||||
|
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class SurveillanceCameraMonitorWindow : DefaultWindow
|
public sealed partial class SurveillanceCameraMonitorWindow : FancyWindow
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
private readonly IPrototypeManager _prototypeManager;
|
||||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
private readonly IEntityManager _entManager;
|
||||||
|
|
||||||
public event Action<string>? CameraSelected;
|
public event Action<NetEntity>? CameraSelected;
|
||||||
public event Action<string>? SubnetOpened;
|
|
||||||
public event Action? CameraRefresh;
|
public event Action? CameraRefresh;
|
||||||
public event Action? SubnetRefresh;
|
public event Action? SubnetRefresh;
|
||||||
public event Action? CameraSwitchTimer;
|
public event Action? CameraSwitchTimer;
|
||||||
@@ -30,110 +31,96 @@ public sealed partial class SurveillanceCameraMonitorWindow : DefaultWindow
|
|||||||
private string _currentAddress = string.Empty;
|
private string _currentAddress = string.Empty;
|
||||||
private bool _isSwitching;
|
private bool _isSwitching;
|
||||||
private readonly FixedEye _defaultEye = new();
|
private readonly FixedEye _defaultEye = new();
|
||||||
private readonly Dictionary<string, int> _subnetMap = new();
|
private Dictionary<NetEntity, CameraData> _cameras = new();
|
||||||
|
private Texture? _blipTexture;
|
||||||
|
private NetEntity? _trackedEntity;
|
||||||
|
|
||||||
private string? SelectedSubnet
|
public SurveillanceCameraMonitorWindow(EntityUid? mapUid)
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (SubnetSelector.ItemCount == 0
|
|
||||||
|| SubnetSelector.SelectedMetadata == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (string) SubnetSelector.SelectedMetadata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SurveillanceCameraMonitorWindow()
|
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
_prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||||
|
var resourceCache = IoCManager.Resolve<IResourceCache>();
|
||||||
|
_entManager = IoCManager.Resolve<IEntityManager>();
|
||||||
|
var spriteSystem = _entManager.System<SpriteSystem>();
|
||||||
|
|
||||||
// This could be done better. I don't want to deal with stylesheets at the moment.
|
// This could be done better. I don't want to deal with stylesheets at the moment.
|
||||||
var texture = _resourceCache.GetTexture("/Textures/Interface/Nano/square_black.png");
|
var texture = resourceCache.GetTexture("/Textures/Interface/Nano/square_black.png");
|
||||||
var shader = _prototypeManager.Index<ShaderPrototype>("CameraStatic").Instance().Duplicate();
|
var shader = _prototypeManager.Index<ShaderPrototype>("CameraStatic").Instance().Duplicate();
|
||||||
|
|
||||||
|
_blipTexture = spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png")));
|
||||||
|
|
||||||
CameraView.ViewportSize = new Vector2i(500, 500);
|
CameraView.ViewportSize = new Vector2i(500, 500);
|
||||||
CameraView.Eye = _defaultEye; // sure
|
CameraView.Eye = _defaultEye; // sure
|
||||||
CameraViewBackground.Stretch = TextureRect.StretchMode.Scale;
|
CameraViewBackground.Stretch = TextureRect.StretchMode.Scale;
|
||||||
CameraViewBackground.Texture = texture;
|
CameraViewBackground.Texture = texture;
|
||||||
CameraViewBackground.ShaderOverride = shader;
|
CameraViewBackground.ShaderOverride = shader;
|
||||||
|
|
||||||
SubnetList.OnItemSelected += OnSubnetListSelect;
|
|
||||||
|
|
||||||
SubnetSelector.OnItemSelected += args =>
|
|
||||||
{
|
|
||||||
// piss
|
|
||||||
SubnetOpened!((string) args.Button.GetItemMetadata(args.Id)!);
|
|
||||||
};
|
|
||||||
SubnetRefreshButton.OnPressed += _ => SubnetRefresh!();
|
SubnetRefreshButton.OnPressed += _ => SubnetRefresh!();
|
||||||
CameraRefreshButton.OnPressed += _ => CameraRefresh!();
|
CameraRefreshButton.OnPressed += _ => CameraRefresh!();
|
||||||
CameraDisconnectButton.OnPressed += _ => CameraDisconnect!();
|
CameraDisconnectButton.OnPressed += _ => CameraDisconnect!();
|
||||||
|
|
||||||
|
NavMap.TrackedEntitySelectedAction += SetTrackedEntityFromNavMap;
|
||||||
|
|
||||||
|
_entManager = IoCManager.Resolve<IEntityManager>();
|
||||||
|
|
||||||
|
if (_entManager.TryGetComponent<TransformComponent>(mapUid, out var xform))
|
||||||
|
NavMap.MapUid = xform.GridUid;
|
||||||
|
else
|
||||||
|
NavMap.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sunrise-start
|
||||||
|
private void SetTrackedEntityFromNavMap(NetEntity? netEntity)
|
||||||
|
{
|
||||||
|
NavMap.Focus = _trackedEntity;
|
||||||
|
|
||||||
|
if (netEntity != null)
|
||||||
|
{
|
||||||
|
CameraSelected!(netEntity.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowCameras(Dictionary<NetEntity, CameraData> cameras, EntityCoordinates? monitorCoords)
|
||||||
|
{
|
||||||
|
ClearAllCamerasPoint();
|
||||||
|
|
||||||
|
_cameras = cameras;
|
||||||
|
|
||||||
|
foreach (var camera in cameras)
|
||||||
|
{
|
||||||
|
NavMap.LocalizedNames.TryAdd(camera.Key, camera.Value.Name);
|
||||||
|
|
||||||
|
var coordinates = _entManager.GetCoordinates(camera.Value.Coordinates);
|
||||||
|
|
||||||
|
if (NavMap.Visible && _blipTexture != null)
|
||||||
|
{
|
||||||
|
NavMap.TrackedEntities.TryAdd(camera.Key,
|
||||||
|
new NavMapBlip(coordinates,
|
||||||
|
_blipTexture,
|
||||||
|
camera.Key == _trackedEntity ? Color.LimeGreen : camera.Value.SubnetColor,
|
||||||
|
camera.Key == _trackedEntity));
|
||||||
|
|
||||||
|
NavMap.Focus = _trackedEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show monitor point
|
||||||
|
if (monitorCoords != null)
|
||||||
|
NavMap.TrackedCoordinates.Add(monitorCoords.Value, (true, StyleNano.PointMagenta));
|
||||||
|
}
|
||||||
|
// Sunrise-end
|
||||||
|
|
||||||
|
|
||||||
// The UI class should get the eye from the entity, and then
|
// The UI class should get the eye from the entity, and then
|
||||||
// pass it here so that the UI can change its view.
|
// pass it here so that the UI can change its view.
|
||||||
public void UpdateState(IEye? eye, HashSet<string> subnets, string activeAddress, string activeSubnet, Dictionary<string, string> cameras)
|
public void UpdateState(IEye? eye, string activeAddress, NetEntity? activeCamera)
|
||||||
{
|
{
|
||||||
_currentAddress = activeAddress;
|
_currentAddress = activeAddress;
|
||||||
|
_trackedEntity = activeCamera;
|
||||||
SetCameraView(eye);
|
SetCameraView(eye);
|
||||||
|
|
||||||
if (subnets.Count == 0)
|
|
||||||
{
|
|
||||||
SubnetSelector.AddItem(Loc.GetString("surveillance-camera-monitor-ui-no-subnets"));
|
|
||||||
SubnetSelector.Disabled = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SubnetSelector.Disabled && subnets.Count != 0)
|
|
||||||
{
|
|
||||||
SubnetSelector.Clear();
|
|
||||||
SubnetSelector.Disabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// That way, we have *a* subnet selected if this is ever opened.
|
|
||||||
if (string.IsNullOrEmpty(activeSubnet))
|
|
||||||
{
|
|
||||||
SubnetOpened!(subnets.First());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the subnet count is unequal, that means
|
|
||||||
// we have to rebuild the subnet selector
|
|
||||||
if (SubnetSelector.ItemCount != subnets.Count)
|
|
||||||
{
|
|
||||||
SubnetSelector.Clear();
|
|
||||||
_subnetMap.Clear();
|
|
||||||
|
|
||||||
foreach (var subnet in subnets)
|
|
||||||
{
|
|
||||||
var id = AddSubnet(subnet);
|
|
||||||
_subnetMap.Add(subnet, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_subnetMap.TryGetValue(activeSubnet, out var subnetId))
|
|
||||||
{
|
|
||||||
SubnetSelector.Select(subnetId);
|
|
||||||
}
|
|
||||||
|
|
||||||
PopulateCameraList(cameras);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PopulateCameraList(Dictionary<string, string> cameras)
|
|
||||||
{
|
|
||||||
SubnetList.Clear();
|
|
||||||
|
|
||||||
foreach (var (address, name) in cameras)
|
|
||||||
{
|
|
||||||
AddCameraToList(name, address);
|
|
||||||
}
|
|
||||||
|
|
||||||
SubnetList.SortItemsByText();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetCameraView(IEye? eye)
|
private void SetCameraView(IEye? eye)
|
||||||
{
|
{
|
||||||
@@ -173,28 +160,9 @@ public sealed partial class SurveillanceCameraMonitorWindow : DefaultWindow
|
|||||||
("address", _currentAddress));
|
("address", _currentAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int AddSubnet(string subnet)
|
private void ClearAllCamerasPoint()
|
||||||
{
|
{
|
||||||
var name = subnet;
|
NavMap.TrackedCoordinates.Clear();
|
||||||
if (_prototypeManager.TryIndex<DeviceFrequencyPrototype>(subnet, out var frequency))
|
NavMap.TrackedEntities.Clear();
|
||||||
{
|
|
||||||
name = Loc.GetString(frequency.Name ?? subnet);
|
|
||||||
}
|
|
||||||
|
|
||||||
SubnetSelector.AddItem(name);
|
|
||||||
SubnetSelector.SetItemMetadata(SubnetSelector.ItemCount - 1, subnet);
|
|
||||||
|
|
||||||
return SubnetSelector.ItemCount - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddCameraToList(string name, string address)
|
|
||||||
{
|
|
||||||
var item = SubnetList.AddItem($"{name}: {address}");
|
|
||||||
item.Metadata = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnSubnetListSelect(ItemList.ItemListSelectedEventArgs args)
|
|
||||||
{
|
|
||||||
CameraSelected!((string) SubnetList[args.ItemIndex].Metadata!);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
using Content.Client.Pinpointer.UI;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.UserInterface.Controls;
|
||||||
|
|
||||||
|
namespace Content.Client.SurveillanceCamera.UI;
|
||||||
|
|
||||||
|
public sealed partial class SurveillanceCameraNavMapControl : NavMapControl
|
||||||
|
{
|
||||||
|
public NetEntity? Focus;
|
||||||
|
public Dictionary<NetEntity, string> LocalizedNames = new();
|
||||||
|
|
||||||
|
private Label _trackedEntityLabel;
|
||||||
|
private PanelContainer _trackedEntityPanel;
|
||||||
|
|
||||||
|
public SurveillanceCameraNavMapControl()
|
||||||
|
{
|
||||||
|
WallColor = new Color(192, 122, 196);
|
||||||
|
TileColor = new(71, 42, 72);
|
||||||
|
BackgroundColor = Color.FromSrgb(TileColor.WithAlpha(BackgroundOpacity));
|
||||||
|
|
||||||
|
_trackedEntityLabel = new Label
|
||||||
|
{
|
||||||
|
Margin = new Thickness(10f, 8f),
|
||||||
|
HorizontalAlignment = HAlignment.Center,
|
||||||
|
VerticalAlignment = VAlignment.Center,
|
||||||
|
Modulate = Color.White,
|
||||||
|
};
|
||||||
|
|
||||||
|
_trackedEntityPanel = new PanelContainer
|
||||||
|
{
|
||||||
|
PanelOverride = new StyleBoxFlat
|
||||||
|
{
|
||||||
|
BackgroundColor = BackgroundColor,
|
||||||
|
},
|
||||||
|
|
||||||
|
Margin = new Thickness(5f, 45f),
|
||||||
|
HorizontalAlignment = HAlignment.Left,
|
||||||
|
VerticalAlignment = VAlignment.Bottom,
|
||||||
|
Visible = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
_trackedEntityPanel.AddChild(_trackedEntityLabel);
|
||||||
|
AddChild(_trackedEntityPanel);
|
||||||
|
VerticalExpand = true;
|
||||||
|
VerticalAlignment = VAlignment.Stretch;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(DrawingHandleScreen handle)
|
||||||
|
{
|
||||||
|
base.Draw(handle);
|
||||||
|
|
||||||
|
if (Focus == null)
|
||||||
|
{
|
||||||
|
_trackedEntityLabel.Text = string.Empty;
|
||||||
|
_trackedEntityPanel.Visible = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ((var netEntity, var blip) in TrackedEntities)
|
||||||
|
{
|
||||||
|
if (netEntity != Focus)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!LocalizedNames.TryGetValue(netEntity, out var name))
|
||||||
|
name = "Unknown";
|
||||||
|
|
||||||
|
var message = name + "\nLocation: [x = " + MathF.Round(blip.Coordinates.X) + ", y = " + MathF.Round(blip.Coordinates.Y) + "]";
|
||||||
|
|
||||||
|
_trackedEntityLabel.Text = message;
|
||||||
|
_trackedEntityPanel.Visible = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_trackedEntityLabel.Text = string.Empty;
|
||||||
|
_trackedEntityPanel.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using Content.Server.Explosion.EntitySystems;
|
|||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Server.Radio;
|
using Content.Server.Radio;
|
||||||
using Content.Server.SurveillanceCamera;
|
using Content.Server.SurveillanceCamera;
|
||||||
|
using Content.Server.SurveillanceCamera.Systems;
|
||||||
using Content.Shared.Emp;
|
using Content.Shared.Emp;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
using Content.Server._White.SurveillanceCamera;
|
using Content.Server._White.SurveillanceCamera;
|
||||||
|
using Content.Server.SurveillanceCamera.Systems;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||||
|
|
||||||
namespace Content.Server.SurveillanceCamera;
|
namespace Content.Server.SurveillanceCamera.Components;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[Access(typeof(SurveillanceCameraSystem), typeof(SurveillanceBodyCameraSystem))]
|
[Access(typeof(SurveillanceCameraSystem), typeof(SurveillanceBodyCameraSystem))]
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
namespace Content.Server.SurveillanceCamera;
|
using Content.Server.SurveillanceCamera.Systems;
|
||||||
|
using Content.Shared.SurveillanceCamera;
|
||||||
|
|
||||||
|
namespace Content.Server.SurveillanceCamera.Components;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[Access(typeof(SurveillanceCameraMonitorSystem))]
|
[Access(typeof(SurveillanceCameraMonitorSystem))]
|
||||||
@@ -29,14 +32,10 @@ public sealed partial class SurveillanceCameraMonitorComponent : Component
|
|||||||
// Set of viewers currently looking at this monitor.
|
// Set of viewers currently looking at this monitor.
|
||||||
public HashSet<EntityUid> Viewers { get; } = new();
|
public HashSet<EntityUid> Viewers { get; } = new();
|
||||||
|
|
||||||
// Current active subnet.
|
|
||||||
[ViewVariables]
|
|
||||||
public string ActiveSubnet { get; set; } = default!;
|
|
||||||
|
|
||||||
// Known cameras in this subnet by address with name values.
|
// Known cameras in this subnet by address with name values.
|
||||||
// This is cleared when the subnet is changed.
|
// This is cleared when the subnet is changed.
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public Dictionary<string, string> KnownCameras { get; } = new();
|
public Dictionary<NetEntity, CameraData> KnownCameras { get; } = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
// The subnets known by this camera monitor.
|
// The subnets known by this camera monitor.
|
||||||
|
|||||||
@@ -28,4 +28,9 @@ public sealed partial class SurveillanceCameraRouterComponent : Component
|
|||||||
|
|
||||||
[DataField("setupAvailableNetworks", customTypeSerializer:typeof(PrototypeIdListSerializer<DeviceFrequencyPrototype>))]
|
[DataField("setupAvailableNetworks", customTypeSerializer:typeof(PrototypeIdListSerializer<DeviceFrequencyPrototype>))]
|
||||||
public List<string> AvailableNetworks { get; private set; } = new();
|
public List<string> AvailableNetworks { get; private set; } = new();
|
||||||
|
|
||||||
|
// Sunrise-start
|
||||||
|
[DataField("subnetColor")]
|
||||||
|
public Color SubnetColor;
|
||||||
|
// Sunrise-end
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
using Content.Server.Chat.Systems;
|
using Content.Server.Chat.Systems;
|
||||||
using Content.Server.Speech;
|
using Content.Server.Speech;
|
||||||
using Content.Server.Speech.Components;
|
using Content.Server.Speech.Components;
|
||||||
|
using Content.Server.SurveillanceCamera.Components;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using static Content.Server.Chat.Systems.ChatSystem;
|
using static Content.Server.Chat.Systems.ChatSystem;
|
||||||
|
|
||||||
namespace Content.Server.SurveillanceCamera;
|
namespace Content.Server.SurveillanceCamera.Systems;
|
||||||
|
|
||||||
public sealed class SurveillanceCameraMicrophoneSystem : EntitySystem
|
public sealed class SurveillanceCameraMicrophoneSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ using System.Linq;
|
|||||||
using Content.Server.DeviceNetwork;
|
using Content.Server.DeviceNetwork;
|
||||||
using Content.Server.DeviceNetwork.Systems;
|
using Content.Server.DeviceNetwork.Systems;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
|
using Content.Server.SurveillanceCamera.Components;
|
||||||
|
using Content.Server.SurveillanceCamera.Systems;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
using Content.Shared.SurveillanceCamera;
|
using Content.Shared.SurveillanceCamera;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Server.SurveillanceCamera;
|
namespace Content.Server.SurveillanceCamera.Systems;
|
||||||
|
|
||||||
public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
||||||
{
|
{
|
||||||
@@ -28,7 +31,6 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
subs.Event<SurveillanceCameraRefreshCamerasMessage>(OnRefreshCamerasMessage);
|
subs.Event<SurveillanceCameraRefreshCamerasMessage>(OnRefreshCamerasMessage);
|
||||||
subs.Event<SurveillanceCameraRefreshSubnetsMessage>(OnRefreshSubnetsMessage);
|
subs.Event<SurveillanceCameraRefreshSubnetsMessage>(OnRefreshSubnetsMessage);
|
||||||
subs.Event<SurveillanceCameraDisconnectMessage>(OnDisconnectMessage);
|
subs.Event<SurveillanceCameraDisconnectMessage>(OnDisconnectMessage);
|
||||||
subs.Event<SurveillanceCameraMonitorSubnetRequestMessage>(OnSubnetRequest);
|
|
||||||
subs.Event<SurveillanceCameraMonitorSwitchMessage>(OnSwitchMessage);
|
subs.Event<SurveillanceCameraMonitorSwitchMessage>(OnSwitchMessage);
|
||||||
subs.Event<BoundUIClosedEvent>(OnBoundUiClose);
|
subs.Event<BoundUIClosedEvent>(OnBoundUiClose);
|
||||||
});
|
});
|
||||||
@@ -87,15 +89,6 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
RefreshSubnets(uid, component);
|
RefreshSubnets(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSubnetRequest(EntityUid uid, SurveillanceCameraMonitorComponent component,
|
|
||||||
SurveillanceCameraMonitorSubnetRequestMessage args)
|
|
||||||
{
|
|
||||||
if (args.Session.AttachedEntity != null)
|
|
||||||
{
|
|
||||||
SetActiveSubnet(uid, args.Subnet, component);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnPacketReceived(EntityUid uid, SurveillanceCameraMonitorComponent component,
|
private void OnPacketReceived(EntityUid uid, SurveillanceCameraMonitorComponent component,
|
||||||
DeviceNetworkPacketEvent args)
|
DeviceNetworkPacketEvent args)
|
||||||
{
|
{
|
||||||
@@ -127,28 +120,48 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
case SurveillanceCameraSystem.CameraDataMessage:
|
case SurveillanceCameraSystem.CameraDataMessage:
|
||||||
if (!args.Data.TryGetValue(SurveillanceCameraSystem.CameraNameData, out string? name)
|
if (!args.Data.TryGetValue(SurveillanceCameraSystem.CameraNameData, out string? name)
|
||||||
|| !args.Data.TryGetValue(SurveillanceCameraSystem.CameraSubnetData, out string? subnetData)
|
|| !args.Data.TryGetValue(SurveillanceCameraSystem.CameraSubnetData, out string? subnetData)
|
||||||
|| !args.Data.TryGetValue(SurveillanceCameraSystem.CameraAddressData, out string? address))
|
|| !args.Data.TryGetValue(SurveillanceCameraSystem.CameraAddressData, out string? address)
|
||||||
|
|| !args.Data.TryGetValue(SurveillanceCameraSystem.CameraUid, out EntityUid cameraUid)
|
||||||
|
|| !args.Data.TryGetValue(SurveillanceCameraSystem.CameraSubnetColor, out Color color))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.ActiveSubnet != subnetData)
|
if (!component.KnownSubnets.TryGetValue(subnetData, out var subnetAddress))
|
||||||
{
|
{
|
||||||
DisconnectFromSubnet(uid, subnetData);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!component.KnownCameras.ContainsKey(address))
|
var netEntCamera = GetNetEntity(cameraUid);
|
||||||
|
|
||||||
|
if (!component.KnownCameras.ContainsKey(netEntCamera))
|
||||||
{
|
{
|
||||||
component.KnownCameras.Add(address, name);
|
var coordinates = EntityCoordinates.Invalid;
|
||||||
|
|
||||||
|
if (TryComp<TransformComponent>(cameraUid, out var transform))
|
||||||
|
{
|
||||||
|
if (transform.GridUid != null)
|
||||||
|
{
|
||||||
|
coordinates = transform.Coordinates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component.KnownCameras.Add(netEntCamera,
|
||||||
|
new CameraData {
|
||||||
|
Name = name,
|
||||||
|
CameraAddress = address,
|
||||||
|
SubnetAddress = subnetAddress,
|
||||||
|
SubnetColor = color,
|
||||||
|
Coordinates = GetNetCoordinates(coordinates)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateUserInterface(uid, component);
|
UpdateUserInterface(uid, component);
|
||||||
break;
|
break;
|
||||||
case SurveillanceCameraSystem.CameraSubnetData:
|
case SurveillanceCameraSystem.CameraSubnetData:
|
||||||
if (args.Data.TryGetValue(SurveillanceCameraSystem.CameraSubnetData, out string? subnet)
|
if (args.Data.TryGetValue(SurveillanceCameraSystem.CameraSubnetData, out string? subnet))
|
||||||
&& !component.KnownSubnets.ContainsKey(subnet))
|
|
||||||
{
|
{
|
||||||
component.KnownSubnets.Add(subnet, args.SenderAddress);
|
component.KnownSubnets.TryAdd(subnet, args.SenderAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateUserInterface(uid, component);
|
UpdateUserInterface(uid, component);
|
||||||
@@ -161,13 +174,30 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
SurveillanceCameraDisconnectMessage message)
|
SurveillanceCameraDisconnectMessage message)
|
||||||
{
|
{
|
||||||
DisconnectCamera(uid, true, component);
|
DisconnectCamera(uid, true, component);
|
||||||
|
// Sunrise-start
|
||||||
|
foreach (var subnet in component.KnownSubnets)
|
||||||
|
{
|
||||||
|
DisconnectFromSubnet(uid, subnet.Key);
|
||||||
|
component.KnownCameras.Clear();
|
||||||
|
UpdateUserInterface(uid, component);
|
||||||
|
ConnectToSubnet(uid, subnet.Key);
|
||||||
|
}
|
||||||
|
// Sunrise-end
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRefreshCamerasMessage(EntityUid uid, SurveillanceCameraMonitorComponent component,
|
private void OnRefreshCamerasMessage(EntityUid uid, SurveillanceCameraMonitorComponent component,
|
||||||
SurveillanceCameraRefreshCamerasMessage message)
|
SurveillanceCameraRefreshCamerasMessage message)
|
||||||
{
|
{
|
||||||
|
// Sunrise-start
|
||||||
|
foreach (var subnet in component.KnownSubnets)
|
||||||
|
{
|
||||||
|
DisconnectFromSubnet(uid, subnet.Key);
|
||||||
|
DisconnectCamera(uid, true, component);
|
||||||
component.KnownCameras.Clear();
|
component.KnownCameras.Clear();
|
||||||
RequestActiveSubnetInfo(uid, component);
|
UpdateUserInterface(uid, component);
|
||||||
|
ConnectToSubnet(uid, subnet.Key);
|
||||||
|
}
|
||||||
|
// Sunrise-end
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRefreshSubnetsMessage(EntityUid uid, SurveillanceCameraMonitorComponent component,
|
private void OnRefreshSubnetsMessage(EntityUid uid, SurveillanceCameraMonitorComponent component,
|
||||||
@@ -181,7 +211,7 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
// there would be a null check here, but honestly
|
// there would be a null check here, but honestly
|
||||||
// whichever one is the "latest" switch message gets to
|
// whichever one is the "latest" switch message gets to
|
||||||
// do the switch
|
// do the switch
|
||||||
TrySwitchCameraByAddress(uid, message.Address, component);
|
TrySwitchCameraByUid(uid, GetEntity(message.CameraNetEntity), component);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPowerChanged(EntityUid uid, SurveillanceCameraMonitorComponent component, ref PowerChangedEvent args)
|
private void OnPowerChanged(EntityUid uid, SurveillanceCameraMonitorComponent component, ref PowerChangedEvent args)
|
||||||
@@ -190,7 +220,6 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
RemoveActiveCamera(uid, component);
|
RemoveActiveCamera(uid, component);
|
||||||
component.NextCameraAddress = null;
|
component.NextCameraAddress = null;
|
||||||
component.ActiveSubnet = string.Empty;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,20 +237,17 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnBoundUiClose(EntityUid uid, SurveillanceCameraMonitorComponent component, BoundUIClosedEvent args)
|
private void OnBoundUiClose(EntityUid uid, SurveillanceCameraMonitorComponent component, BoundUIClosedEvent args)
|
||||||
{
|
{
|
||||||
if (args.Session.AttachedEntity == null)
|
RemoveViewer(uid, args.Entity, component);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveViewer(uid, args.Session.AttachedEntity.Value, component);
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void SendHeartbeat(EntityUid uid, SurveillanceCameraMonitorComponent? monitor = null)
|
private void SendHeartbeat(EntityUid uid, SurveillanceCameraMonitorComponent? monitor = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref monitor)
|
if (!Resolve(uid, ref monitor)
|
||||||
|| monitor.LastHeartbeatSent < _heartbeatDelay
|
|| monitor.LastHeartbeatSent < _heartbeatDelay
|
||||||
|| !monitor.KnownSubnets.TryGetValue(monitor.ActiveSubnet, out var subnetAddress))
|
|| monitor.ActiveCamera == null
|
||||||
|
|| !monitor.KnownCameras.TryGetValue(GetNetEntity(monitor.ActiveCamera.Value), out var cameraData))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -232,7 +258,7 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
{ SurveillanceCameraSystem.CameraAddressData, monitor.ActiveCameraAddress }
|
{ SurveillanceCameraSystem.CameraAddressData, monitor.ActiveCameraAddress }
|
||||||
};
|
};
|
||||||
|
|
||||||
_deviceNetworkSystem.QueuePacket(uid, subnetAddress, payload);
|
_deviceNetworkSystem.QueuePacket(uid, cameraData.SubnetAddress, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisconnectCamera(EntityUid uid, bool removeViewers, SurveillanceCameraMonitorComponent? monitor = null)
|
private void DisconnectCamera(EntityUid uid, bool removeViewers, SurveillanceCameraMonitorComponent? monitor = null)
|
||||||
@@ -278,28 +304,10 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
_deviceNetworkSystem.QueuePacket(uid, null, payload);
|
_deviceNetworkSystem.QueuePacket(uid, null, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetActiveSubnet(EntityUid uid, string subnet,
|
private void RequestSubnetInfo(EntityUid uid, string subnet, SurveillanceCameraMonitorComponent? monitor = null)
|
||||||
SurveillanceCameraMonitorComponent? monitor = null)
|
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref monitor)
|
if (!Resolve(uid, ref monitor)
|
||||||
|| !monitor.KnownSubnets.ContainsKey(subnet))
|
|| !monitor.KnownSubnets.TryGetValue(subnet, out var address))
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisconnectFromSubnet(uid, monitor.ActiveSubnet);
|
|
||||||
DisconnectCamera(uid, true, monitor);
|
|
||||||
monitor.ActiveSubnet = subnet;
|
|
||||||
monitor.KnownCameras.Clear();
|
|
||||||
UpdateUserInterface(uid, monitor);
|
|
||||||
|
|
||||||
ConnectToSubnet(uid, subnet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RequestActiveSubnetInfo(EntityUid uid, SurveillanceCameraMonitorComponent? monitor = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref monitor)
|
|
||||||
|| !monitor.KnownSubnets.TryGetValue(monitor.ActiveSubnet, out var address))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -325,7 +333,7 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
};
|
};
|
||||||
_deviceNetworkSystem.QueuePacket(uid, address, payload);
|
_deviceNetworkSystem.QueuePacket(uid, address, payload);
|
||||||
|
|
||||||
RequestActiveSubnetInfo(uid);
|
RequestSubnetInfo(uid, subnet, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisconnectFromSubnet(EntityUid uid, string subnet, SurveillanceCameraMonitorComponent? monitor = null)
|
private void DisconnectFromSubnet(EntityUid uid, string subnet, SurveillanceCameraMonitorComponent? monitor = null)
|
||||||
@@ -415,11 +423,12 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
UpdateUserInterface(uid, monitor);
|
UpdateUserInterface(uid, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TrySwitchCameraByAddress(EntityUid uid, string address,
|
private void TrySwitchCameraByAddress(EntityUid uid,
|
||||||
|
string camera,
|
||||||
|
string subnet,
|
||||||
SurveillanceCameraMonitorComponent? monitor = null)
|
SurveillanceCameraMonitorComponent? monitor = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref monitor)
|
if (!Resolve(uid, ref monitor))
|
||||||
|| !monitor.KnownSubnets.TryGetValue(monitor.ActiveSubnet, out var subnetAddress))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -427,11 +436,11 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
var payload = new NetworkPayload()
|
var payload = new NetworkPayload()
|
||||||
{
|
{
|
||||||
{DeviceNetworkConstants.Command, SurveillanceCameraSystem.CameraConnectMessage},
|
{DeviceNetworkConstants.Command, SurveillanceCameraSystem.CameraConnectMessage},
|
||||||
{SurveillanceCameraSystem.CameraAddressData, address}
|
{SurveillanceCameraSystem.CameraAddressData, camera}
|
||||||
};
|
};
|
||||||
|
|
||||||
monitor.NextCameraAddress = address;
|
monitor.NextCameraAddress = camera;
|
||||||
_deviceNetworkSystem.QueuePacket(uid, subnetAddress, payload);
|
_deviceNetworkSystem.QueuePacket(uid, subnet, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempts to switch over the current viewed camera on this monitor
|
// Attempts to switch over the current viewed camera on this monitor
|
||||||
@@ -486,7 +495,7 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var state = new SurveillanceCameraMonitorUiState(GetNetEntity(monitor.ActiveCamera), monitor.KnownSubnets.Keys.ToHashSet(), monitor.ActiveCameraAddress, monitor.ActiveSubnet, monitor.KnownCameras);
|
var state = new SurveillanceCameraMonitorUiState(GetNetEntity(monitor.ActiveCamera), monitor.KnownSubnets.Keys.ToHashSet(), monitor.ActiveCameraAddress, monitor.KnownCameras);
|
||||||
_userInterface.TrySetUiState(uid, SurveillanceCameraMonitorUiKey.Key, state);
|
_userInterface.TrySetUiState(uid, SurveillanceCameraMonitorUiKey.Key, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ using Content.Server.DeviceNetwork;
|
|||||||
using Content.Server.DeviceNetwork.Components;
|
using Content.Server.DeviceNetwork.Components;
|
||||||
using Content.Server.DeviceNetwork.Systems;
|
using Content.Server.DeviceNetwork.Systems;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
|
using Content.Server.SurveillanceCamera;
|
||||||
|
using Content.Server.SurveillanceCamera.Systems;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
using Content.Shared.SurveillanceCamera;
|
using Content.Shared.SurveillanceCamera;
|
||||||
@@ -10,7 +12,7 @@ using Robust.Server.GameObjects;
|
|||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.SurveillanceCamera;
|
namespace Content.Server.SurveillanceCamera.Systems;
|
||||||
|
|
||||||
public sealed class SurveillanceCameraRouterSystem : EntitySystem
|
public sealed class SurveillanceCameraRouterSystem : EntitySystem
|
||||||
{
|
{
|
||||||
@@ -244,7 +246,8 @@ public sealed class SurveillanceCameraRouterSystem : EntitySystem
|
|||||||
var payload = new NetworkPayload()
|
var payload = new NetworkPayload()
|
||||||
{
|
{
|
||||||
{ DeviceNetworkConstants.Command, SurveillanceCameraSystem.CameraPingMessage },
|
{ DeviceNetworkConstants.Command, SurveillanceCameraSystem.CameraPingMessage },
|
||||||
{ SurveillanceCameraSystem.CameraSubnetData, router.SubnetName }
|
{ SurveillanceCameraSystem.CameraSubnetData, router.SubnetName },
|
||||||
|
{ SurveillanceCameraSystem.CameraSubnetColor, router.SubnetColor}
|
||||||
};
|
};
|
||||||
|
|
||||||
_deviceNetworkSystem.QueuePacket(uid, null, payload, router.SubnetFrequency);
|
_deviceNetworkSystem.QueuePacket(uid, null, payload, router.SubnetFrequency);
|
||||||
@@ -257,6 +260,10 @@ public sealed class SurveillanceCameraRouterSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
payload[SurveillanceCameraSystem.CameraSubnetData] = router.SubnetFrequencyId;
|
||||||
|
payload[SurveillanceCameraSystem.CameraSubnetColor] = router.SubnetColor;
|
||||||
|
|
||||||
|
payload[SurveillanceCameraSystem.CameraSubnetData] = router.SubnetFrequencyId;
|
||||||
|
|
||||||
foreach (var address in router.MonitorRoutes)
|
foreach (var address in router.MonitorRoutes)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using Content.Shared.Speech;
|
|||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Server.SurveillanceCamera;
|
namespace Content.Server.SurveillanceCamera.Systems;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This handles speech for surveillance camera monitors.
|
/// This handles speech for surveillance camera monitors.
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork.Components;
|
|||||||
using Content.Server.DeviceNetwork.Systems;
|
using Content.Server.DeviceNetwork.Systems;
|
||||||
using Content.Server.Emp;
|
using Content.Server.Emp;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
|
using Content.Server.SurveillanceCamera.Components;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
using Content.Shared.SurveillanceCamera;
|
using Content.Shared.SurveillanceCamera;
|
||||||
@@ -12,7 +13,7 @@ using Robust.Server.GameObjects;
|
|||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.SurveillanceCamera;
|
namespace Content.Server.SurveillanceCamera.Systems;
|
||||||
|
|
||||||
public sealed class SurveillanceCameraSystem : EntitySystem
|
public sealed class SurveillanceCameraSystem : EntitySystem
|
||||||
{
|
{
|
||||||
@@ -47,8 +48,10 @@ public sealed class SurveillanceCameraSystem : EntitySystem
|
|||||||
public const string CameraSubnetDisconnectMessage = "surveillance_camera_subnet_disconnect";
|
public const string CameraSubnetDisconnectMessage = "surveillance_camera_subnet_disconnect";
|
||||||
|
|
||||||
public const string CameraAddressData = "surveillance_camera_data_origin";
|
public const string CameraAddressData = "surveillance_camera_data_origin";
|
||||||
|
public const string CameraUid = "surveillance_camera_data_uid";
|
||||||
public const string CameraNameData = "surveillance_camera_data_name";
|
public const string CameraNameData = "surveillance_camera_data_name";
|
||||||
public const string CameraSubnetData = "surveillance_camera_data_subnet";
|
public const string CameraSubnetData = "surveillance_camera_data_subnet";
|
||||||
|
public const string CameraSubnetColor = "surveillance_camera_color_subnet";
|
||||||
|
|
||||||
public const int CameraNameLimit = 32;
|
public const int CameraNameLimit = 32;
|
||||||
|
|
||||||
@@ -84,7 +87,9 @@ public sealed class SurveillanceCameraSystem : EntitySystem
|
|||||||
{ DeviceNetworkConstants.Command, string.Empty },
|
{ DeviceNetworkConstants.Command, string.Empty },
|
||||||
{ CameraAddressData, deviceNet.Address },
|
{ CameraAddressData, deviceNet.Address },
|
||||||
{ CameraNameData, component.CameraId },
|
{ CameraNameData, component.CameraId },
|
||||||
{ CameraSubnetData, string.Empty }
|
{ CameraSubnetData, string.Empty },
|
||||||
|
{ CameraSubnetColor, new Color() },
|
||||||
|
{ CameraUid, uid }
|
||||||
};
|
};
|
||||||
|
|
||||||
var dest = string.Empty;
|
var dest = string.Empty;
|
||||||
@@ -92,60 +97,50 @@ public sealed class SurveillanceCameraSystem : EntitySystem
|
|||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case CameraConnectMessage:
|
case CameraConnectMessage:
|
||||||
if (!args.Data.TryGetValue(CameraAddressData, out dest)
|
if (!args.Data.TryGetValue(CameraAddressData, out dest) || string.IsNullOrEmpty(args.Address))
|
||||||
|| string.IsNullOrEmpty(args.Address))
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
payload[DeviceNetworkConstants.Command] = CameraConnectMessage;
|
payload[DeviceNetworkConstants.Command] = CameraConnectMessage;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraHeartbeatMessage:
|
case CameraHeartbeatMessage:
|
||||||
if (!args.Data.TryGetValue(CameraAddressData, out dest)
|
if (!args.Data.TryGetValue(CameraAddressData, out dest) || string.IsNullOrEmpty(args.Address))
|
||||||
|| string.IsNullOrEmpty(args.Address))
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
payload[DeviceNetworkConstants.Command] = CameraHeartbeatMessage;
|
payload[DeviceNetworkConstants.Command] = CameraHeartbeatMessage;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CameraPingMessage:
|
case CameraPingMessage:
|
||||||
if (!args.Data.TryGetValue(CameraSubnetData, out string? subnet))
|
if (!args.Data.TryGetValue(CameraSubnetData, out string? subnet))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
if (!args.Data.TryGetValue(CameraSubnetColor, out Color color))
|
||||||
|
return;
|
||||||
|
|
||||||
dest = args.SenderAddress;
|
dest = args.SenderAddress;
|
||||||
payload[CameraSubnetData] = subnet;
|
payload[CameraSubnetData] = subnet;
|
||||||
|
payload[CameraSubnetColor] = color;
|
||||||
|
payload[CameraUid] = uid;
|
||||||
payload[DeviceNetworkConstants.Command] = CameraDataMessage;
|
payload[DeviceNetworkConstants.Command] = CameraDataMessage;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_deviceNetworkSystem.QueuePacket(
|
_deviceNetworkSystem.QueuePacket(uid, dest, payload);
|
||||||
uid,
|
|
||||||
dest,
|
|
||||||
payload);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddVerbs(EntityUid uid, SurveillanceCameraComponent component, GetVerbsEvent<AlternativeVerb> verbs)
|
private void AddVerbs(EntityUid uid, SurveillanceCameraComponent component, GetVerbsEvent<AlternativeVerb> verbs)
|
||||||
{
|
{
|
||||||
if (!_actionBlocker.CanInteract(verbs.User, uid))
|
if (!_actionBlocker.CanInteract(verbs.User, uid))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (TryComp<SurveillanceBodyCameraComponent>(uid, out _)) // WD EDIT
|
if (HasComp<SurveillanceBodyCameraComponent>(uid)) // WD EDIT
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (component.NameSet && component.NetworkSet)
|
if (component.NameSet && component.NetworkSet)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
AlternativeVerb verb = new();
|
var verb = new AlternativeVerb();
|
||||||
verb.Text = Loc.GetString("surveillance-camera-setup");
|
verb.Text = Loc.GetString("surveillance-camera-setup");
|
||||||
verb.Act = () => OpenSetupInterface(uid, verbs.User, component);
|
verb.Act = () => OpenSetupInterface(uid, verbs.User, component);
|
||||||
verbs.Verbs.Add(verb);
|
verbs.Verbs.Add(verb);
|
||||||
@@ -181,21 +176,14 @@ public sealed class SurveillanceCameraSystem : EntitySystem
|
|||||||
private void OnSetNetwork(EntityUid uid, SurveillanceCameraComponent component,
|
private void OnSetNetwork(EntityUid uid, SurveillanceCameraComponent component,
|
||||||
SurveillanceCameraSetupSetNetwork args)
|
SurveillanceCameraSetupSetNetwork args)
|
||||||
{
|
{
|
||||||
if (args.UiKey is not SurveillanceCameraSetupUiKey key
|
if (args.UiKey is not SurveillanceCameraSetupUiKey key || key != SurveillanceCameraSetupUiKey.Camera)
|
||||||
|| key != SurveillanceCameraSetupUiKey.Camera)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (args.Network < 0 || args.Network >= component.AvailableNetworks.Count)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_prototypeManager.TryIndex<DeviceFrequencyPrototype>(component.AvailableNetworks[args.Network],
|
if (args.Network < 0 || args.Network >= component.AvailableNetworks.Count)
|
||||||
out var frequency))
|
return;
|
||||||
{
|
|
||||||
|
if (!_prototypeManager.TryIndex<DeviceFrequencyPrototype>(component.AvailableNetworks[args.Network], out var frequency))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
_deviceNetworkSystem.SetReceiveFrequency(uid, frequency.Frequency);
|
_deviceNetworkSystem.SetReceiveFrequency(uid, frequency.Frequency);
|
||||||
component.NetworkSet = true;
|
component.NetworkSet = true;
|
||||||
@@ -206,6 +194,7 @@ public sealed class SurveillanceCameraSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
if (!Resolve(uid, ref camera) || !Resolve(player, ref actor))
|
if (!Resolve(uid, ref camera) || !Resolve(player, ref actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_userInterface.TryGetUi(uid, SurveillanceCameraSetupUiKey.Camera, out var bui))
|
if (!_userInterface.TryGetUi(uid, SurveillanceCameraSetupUiKey.Camera, out var bui))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -216,9 +205,7 @@ public sealed class SurveillanceCameraSystem : EntitySystem
|
|||||||
public void UpdateSetupInterface(EntityUid uid, SurveillanceCameraComponent? camera = null, DeviceNetworkComponent? deviceNet = null)
|
public void UpdateSetupInterface(EntityUid uid, SurveillanceCameraComponent? camera = null, DeviceNetworkComponent? deviceNet = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref camera, ref deviceNet))
|
if (!Resolve(uid, ref camera, ref deviceNet))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (camera.NameSet && camera.NetworkSet && !TryComp<SurveillanceBodyCameraComponent>(uid, out _)) // WD EDIT
|
if (camera.NameSet && camera.NetworkSet && !TryComp<SurveillanceBodyCameraComponent>(uid, out _)) // WD EDIT
|
||||||
{
|
{
|
||||||
@@ -249,9 +236,7 @@ public sealed class SurveillanceCameraSystem : EntitySystem
|
|||||||
private void Deactivate(EntityUid camera, SurveillanceCameraComponent? component = null)
|
private void Deactivate(EntityUid camera, SurveillanceCameraComponent? component = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(camera, ref component))
|
if (!Resolve(camera, ref component))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var ev = new SurveillanceCameraDeactivateEvent(camera);
|
var ev = new SurveillanceCameraDeactivateEvent(camera);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Server.PowerCell;
|
using Content.Server.PowerCell;
|
||||||
using Content.Server.SurveillanceCamera;
|
using Content.Server.SurveillanceCamera;
|
||||||
|
using Content.Server.SurveillanceCamera.Components;
|
||||||
|
using Content.Server.SurveillanceCamera.Systems;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Clothing.EntitySystems;
|
using Content.Shared.Clothing.EntitySystems;
|
||||||
using Content.Shared.Item;
|
using Content.Shared.Item;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.SurveillanceCamera;
|
namespace Content.Shared.SurveillanceCamera;
|
||||||
@@ -17,30 +18,39 @@ public sealed class SurveillanceCameraMonitorUiState : BoundUserInterfaceState
|
|||||||
|
|
||||||
public string ActiveAddress;
|
public string ActiveAddress;
|
||||||
|
|
||||||
// Currently active subnet.
|
|
||||||
public string ActiveSubnet { get; }
|
|
||||||
|
|
||||||
// Known cameras, by address and name.
|
// Known cameras, by address and name.
|
||||||
public Dictionary<string, string> Cameras { get; }
|
public Dictionary<NetEntity, CameraData> Cameras { get; }
|
||||||
|
|
||||||
public SurveillanceCameraMonitorUiState(NetEntity? activeCamera, HashSet<string> subnets, string activeAddress, string activeSubnet, Dictionary<string, string> cameras)
|
public SurveillanceCameraMonitorUiState(NetEntity? activeCamera, HashSet<string> subnets, string activeAddress, Dictionary<NetEntity, CameraData> cameras)
|
||||||
{
|
{
|
||||||
ActiveCamera = activeCamera;
|
ActiveCamera = activeCamera;
|
||||||
Subnets = subnets;
|
Subnets = subnets;
|
||||||
ActiveAddress = activeAddress;
|
ActiveAddress = activeAddress;
|
||||||
ActiveSubnet = activeSubnet;
|
|
||||||
Cameras = cameras;
|
Cameras = cameras;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sunrise-start
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
[DataDefinition]
|
||||||
|
public partial class CameraData
|
||||||
|
{
|
||||||
|
public string CameraAddress { get; set; }
|
||||||
|
public string SubnetAddress { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public NetCoordinates Coordinates { get; set; }
|
||||||
|
public Color SubnetColor { get; set; }
|
||||||
|
}
|
||||||
|
// Sunrise-end
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class SurveillanceCameraMonitorSwitchMessage : BoundUserInterfaceMessage
|
public sealed class SurveillanceCameraMonitorSwitchMessage : BoundUserInterfaceMessage
|
||||||
{
|
{
|
||||||
public string Address { get; }
|
public NetEntity CameraNetEntity { get; }
|
||||||
|
|
||||||
public SurveillanceCameraMonitorSwitchMessage(string address)
|
public SurveillanceCameraMonitorSwitchMessage(NetEntity camera)
|
||||||
{
|
{
|
||||||
Address = address;
|
CameraNetEntity = camera;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
0
Resources/Changelog/ChangelogSunrise.yml
Normal file
0
Resources/Changelog/ChangelogSunrise.yml
Normal file
@@ -11,3 +11,6 @@ surveillance-camera-setup = Настроить
|
|||||||
surveillance-camera-setup-ui-set = Установить
|
surveillance-camera-setup-ui-set = Установить
|
||||||
surveillance-body-camera-on = { $item } начинает мигать
|
surveillance-body-camera-on = { $item } начинает мигать
|
||||||
surveillance-body-camera-off = { $item } перестает мигать
|
surveillance-body-camera-off = { $item } перестает мигать
|
||||||
|
|
||||||
|
surveillance-camera-monitor-ui-flavor-left = Большой брат смотрит.
|
||||||
|
surveillance-camera-monitor-ui-flavor-right = v1.984
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
- SurveillanceCameraGeneral
|
- SurveillanceCameraGeneral
|
||||||
- SurveillanceCameraMedical
|
- SurveillanceCameraMedical
|
||||||
- SurveillanceCameraCommand
|
- SurveillanceCameraCommand
|
||||||
|
subnetColor: "#088743"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -46,6 +47,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraEngineering
|
subnetFrequency: SurveillanceCameraEngineering
|
||||||
|
subnetColor: "#EFB341"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -54,6 +56,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraSecurity
|
subnetFrequency: SurveillanceCameraSecurity
|
||||||
|
subnetColor: "#DE3A3A"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -62,6 +65,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraScience
|
subnetFrequency: SurveillanceCameraScience
|
||||||
|
subnetColor: "#D381C9"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -70,6 +74,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraSupply
|
subnetFrequency: SurveillanceCameraSupply
|
||||||
|
subnetColor: "#A46106"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -78,6 +83,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraCommand
|
subnetFrequency: SurveillanceCameraCommand
|
||||||
|
subnetColor: "#052EED"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -86,6 +92,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraService
|
subnetFrequency: SurveillanceCameraService
|
||||||
|
subnetColor: "#9FED58"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -94,6 +101,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraMedical
|
subnetFrequency: SurveillanceCameraMedical
|
||||||
|
subnetColor: "#52B4E9"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraRouterBase
|
parent: SurveillanceCameraRouterBase
|
||||||
@@ -102,6 +110,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraGeneral
|
subnetFrequency: SurveillanceCameraGeneral
|
||||||
|
subnetColor: "#088743"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: [ BaseMachinePowered, ConstructibleMachine ]
|
parent: [ BaseMachinePowered, ConstructibleMachine ]
|
||||||
@@ -136,6 +145,7 @@
|
|||||||
setupAvailableNetworks:
|
setupAvailableNetworks:
|
||||||
- SurveillanceCameraEntertainment
|
- SurveillanceCameraEntertainment
|
||||||
- SurveillanceCameraSecurity
|
- SurveillanceCameraSecurity
|
||||||
|
subnetColor: "#088743"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: SurveillanceCameraWirelessRouterBase
|
parent: SurveillanceCameraWirelessRouterBase
|
||||||
@@ -144,6 +154,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: SurveillanceCameraRouter
|
- type: SurveillanceCameraRouter
|
||||||
subnetFrequency: SurveillanceCameraEntertainment
|
subnetFrequency: SurveillanceCameraEntertainment
|
||||||
|
subnetColor: "#088743"
|
||||||
|
|
||||||
# Body Camera Separate Router
|
# Body Camera Separate Router
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
0
Resources/Prototypes/_White/portable_computers.yml
Normal file
0
Resources/Prototypes/_White/portable_computers.yml
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 701 B |
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "",
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user