]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Predict two-way levers (#25043)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Sun, 11 Feb 2024 03:19:45 +0000 (14:19 +1100)
committerGitHub <noreply@github.com>
Sun, 11 Feb 2024 03:19:45 +0000 (14:19 +1100)
* Predict two-way levers

Annoys me the rare occasions I touch cargo. Doesn't predict the signal but at least the lever responds immediately.

* space

* a

35 files changed:
Content.Benchmarks/DeviceNetworkingBenchmark.cs
Content.Client/DeviceLinking/DeviceLinkSystem.cs [new file with mode: 0644]
Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTest.cs
Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTestSystem.cs
Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs
Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs
Content.Server/Atmos/Monitor/Systems/AtmosDeviceNetwork.cs
Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs
Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs
Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs
Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs
Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs
Content.Server/Communications/CommunicationsConsoleSystem.cs
Content.Server/DeviceLinking/Components/TwoWayLeverComponent.cs [deleted file]
Content.Server/DeviceLinking/Events/SignalReceivedEvent.cs
Content.Server/DeviceLinking/Systems/DeviceLinkSystem.cs
Content.Server/DeviceLinking/Systems/DoorSignalControlSystem.cs
Content.Server/DeviceNetwork/NetworkPayload.cs [deleted file]
Content.Server/DeviceNetwork/Systems/Devices/ApcNetSwitchSystem.cs
Content.Server/Disposal/Mailing/MailingUnitSystem.cs
Content.Server/Fax/FaxSystem.cs
Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs
Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
Content.Server/Power/Generation/Teg/TegSystem.cs
Content.Server/RoundEnd/RoundEndSystem.cs
Content.Server/SensorMonitoring/BatterySensorSystem.cs
Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.cs
Content.Server/Shuttles/Systems/ArrivalsSystem.cs
Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs
Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs
Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs
Content.Shared/DeviceLinking/Components/TwoWayLeverComponent.cs [new file with mode: 0644]
Content.Shared/DeviceLinking/SharedDeviceLinkSystem.cs
Content.Shared/DeviceLinking/Systems/TwoWayLeverSystem.cs [moved from Content.Server/DeviceLinking/Systems/TwoWayLeverSystem.cs with 95% similarity]
Content.Shared/DeviceNetwork/NetworkPayload.cs [new file with mode: 0644]

index 16805c2684f25e63ac480dcd69abf21ba9603dc2..bb2a22312ea82c1723055d9f60da18d607e302d3 100644 (file)
@@ -4,8 +4,8 @@ using BenchmarkDotNet.Attributes;
 using Content.IntegrationTests;
 using Content.IntegrationTests.Pair;
 using Content.IntegrationTests.Tests.DeviceNetwork;
-using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Systems;
+using Content.Shared.DeviceNetwork;
 using Robust.Shared;
 using Robust.Shared.Analyzers;
 using Robust.Shared.GameObjects;
diff --git a/Content.Client/DeviceLinking/DeviceLinkSystem.cs b/Content.Client/DeviceLinking/DeviceLinkSystem.cs
new file mode 100644 (file)
index 0000000..3356e34
--- /dev/null
@@ -0,0 +1,8 @@
+using Content.Shared.DeviceLinking;
+
+namespace Content.Client.DeviceLinking;
+
+public sealed class DeviceLinkSystem : SharedDeviceLinkSystem
+{
+
+}
index 1d994624a6de8b6045e25f4bdefdd807fa2056b0..26ea726211b935cfd2a2255499f96e05d32ecaa7 100644 (file)
@@ -2,6 +2,7 @@ using System.Numerics;
 using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Components;
 using Content.Server.DeviceNetwork.Systems;
+using Content.Shared.DeviceNetwork;
 using Robust.Shared.GameObjects;
 using Robust.Shared.IoC;
 using Robust.Shared.Map;
index 6e3db254047e1ba4b8b7b510cbc2ce7f475eadf9..400d85f2ccb481522a57a1e460a6d420d307f1e4 100644 (file)
@@ -1,7 +1,6 @@
-
-using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Components;
 using Content.Server.DeviceNetwork.Systems;
+using Content.Shared.DeviceNetwork;
 using Robust.Shared.GameObjects;
 using Robust.Shared.Reflection;
 
index b346fd63b0da61d27dc876713f7ae4f800de6beb..2922d0796a9bde888327044397ee2168f5f630d8 100644 (file)
@@ -15,6 +15,7 @@ using Content.Shared.Atmos.Monitor;
 using Content.Shared.Atmos.Monitor.Components;
 using Content.Shared.Atmos.Piping.Unary.Components;
 using Content.Shared.DeviceLinking;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.DeviceNetwork.Systems;
 using Content.Shared.Interaction;
 using Content.Shared.Wires;
index 27e64a9956d8a156b31eff049f6872d574218cea..2875d4a3d5d32d39d21889bce90c3da068f183a1 100644 (file)
@@ -6,6 +6,7 @@ using Content.Server.DeviceNetwork.Components;
 using Content.Server.DeviceNetwork.Systems;
 using Content.Server.Power.Components;
 using Content.Shared.Atmos.Monitor;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Tag;
 using Robust.Server.Audio;
 using Robust.Server.GameObjects;
index 0b73ea5f351570b06b19479cf81fff4a2204639e..33e4eafc741c25e3f18616b20d5da36bd834853c 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Systems;
 using Content.Shared.Atmos.Monitor.Components;
+using Content.Shared.DeviceNetwork;
 
 namespace Content.Server.Atmos.Monitor.Systems;
 
index 1fcb7734d8bad1a15e166d8c17cd6a6c6219e29b..28a0a01c99af13e84586bbe3824896af703f5d06 100644 (file)
@@ -8,6 +8,7 @@ using Content.Server.Power.Components;
 using Content.Server.Power.EntitySystems;
 using Content.Shared.Atmos;
 using Content.Shared.Atmos.Monitor;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Tag;
 using Robust.Shared.Prototypes;
 
index 4ae0d70f5e7dce7e5b16b9b94bcb5e0a97cd23b5..10b9cccc0991defc349331bb70d1df5a6ebd866c 100644 (file)
@@ -13,6 +13,7 @@ using Content.Shared.Atmos.Piping.Binary.Components;
 using Content.Shared.Atmos.Visuals;
 using Content.Shared.Audio;
 using Content.Shared.Database;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Examine;
 using Content.Shared.Interaction;
 using Content.Shared.Popups;
index ee0dca0fb0a901ff0e1ac6afa1137aef9bbb84d7..645b2ecc459dcf6f3c8057ead6dc651a50591811 100644 (file)
@@ -17,6 +17,7 @@ using Content.Server.Power.EntitySystems;
 using Content.Shared.UserInterface;
 using Content.Shared.Administration.Logs;
 using Content.Shared.Database;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Examine;
 
 namespace Content.Server.Atmos.Piping.Unary.EntitySystems
index a35c6b1aa6e3e2c549db370dddc8aa1db531aac9..3a3ccf7523409d049954ff08435ce4641b845cbd 100644 (file)
@@ -16,6 +16,7 @@ using Content.Shared.Atmos.Monitor;
 using Content.Shared.Atmos.Piping.Unary.Components;
 using Content.Shared.Atmos.Visuals;
 using Content.Shared.Audio;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Examine;
 using Content.Shared.Tools.Systems;
 using JetBrains.Annotations;
index ecf7d1d0b45a7b7df28608fbc427d9fa8e10fe49..32591e9c5409b08e59d7f4532ebfcc8ec3fbb5e1 100644 (file)
@@ -15,6 +15,7 @@ using Content.Shared.Atmos.Piping.Unary.Visuals;
 using Content.Shared.Atmos.Monitor;
 using Content.Shared.Atmos.Piping.Unary.Components;
 using Content.Shared.Audio;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Tools.Systems;
 using JetBrains.Annotations;
 using Robust.Server.GameObjects;
index 4fa60563bddba80fba76da718a30c2ecbf3cfc3d..6b0b13c410eae6219c62b5cc3a599f866ad9ea9c 100644 (file)
@@ -19,6 +19,7 @@ using Content.Shared.CCVar;
 using Content.Shared.Chat;
 using Content.Shared.Communications;
 using Content.Shared.Database;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Emag.Components;
 using Content.Shared.Popups;
 using Robust.Server.GameObjects;
diff --git a/Content.Server/DeviceLinking/Components/TwoWayLeverComponent.cs b/Content.Server/DeviceLinking/Components/TwoWayLeverComponent.cs
deleted file mode 100644 (file)
index bbf78b6..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-using Content.Shared.DeviceLinking;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-
-namespace Content.Server.DeviceLinking.Components
-{
-    [RegisterComponent]
-    public sealed partial class TwoWayLeverComponent : Component
-    {
-        [DataField("state")]
-        public TwoWayLeverState State;
-
-        [DataField("nextSignalLeft")]
-        public bool NextSignalLeft;
-
-        [DataField("leftPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
-        public string LeftPort = "Left";
-
-        [DataField("rightPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
-        public string RightPort = "Right";
-
-        [DataField("middlePort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
-        public string MiddlePort = "Middle";
-    }
-}
index c1928575febeed884e1d7fa549dbcb9e6cf6886a..c8c611103d9ff46aeaabef0b65d1e83919fe3f61 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.DeviceNetwork;
+using Content.Shared.DeviceNetwork;
 
 namespace Content.Server.DeviceLinking.Events;
 
index 47f632843d3bf5438727465f560a060381e0fb13..e54e21316f25ed922f0eb8de371f1b6f1d273fe2 100644 (file)
@@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Components;
 using Content.Server.DeviceNetwork.Systems;
 using Content.Shared.DeviceLinking;
+using Content.Shared.DeviceNetwork;
 
 namespace Content.Server.DeviceLinking.Systems;
 
@@ -35,15 +36,7 @@ public sealed class DeviceLinkSystem : SharedDeviceLinkSystem
     }
 
     #region Sending & Receiving
-    /// <summary>
-    /// Sends a network payload directed at the sink entity.
-    /// Just raises a <see cref="SignalReceivedEvent"/> without data if the source or the sink doesn't have a <see cref="DeviceNetworkComponent"/>
-    /// </summary>
-    /// <param name="uid">The source uid that invokes the port</param>
-    /// <param name="port">The port to invoke</param>
-    /// <param name="data">Optional data to send along</param>
-    /// <param name="sourceComponent"></param>
-    public void InvokePort(EntityUid uid, string port, NetworkPayload? data = null, DeviceLinkSourceComponent? sourceComponent = null)
+    public override void InvokePort(EntityUid uid, string port, NetworkPayload? data = null, DeviceLinkSourceComponent? sourceComponent = null)
     {
         if (!Resolve(uid, ref sourceComponent) || !sourceComponent.Outputs.TryGetValue(port, out var sinks))
             return;
index 90623dbae377870ac4e09d914a1dcb753646c23a..40feda32f2b0c1075d250944b72726c23586222a 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Server.DeviceLinking.Components;
 using Content.Server.DeviceNetwork;
 using Content.Server.Doors.Systems;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Doors.Components;
 using Content.Shared.Doors;
 using JetBrains.Annotations;
diff --git a/Content.Server/DeviceNetwork/NetworkPayload.cs b/Content.Server/DeviceNetwork/NetworkPayload.cs
deleted file mode 100644 (file)
index eefbaa6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-using Robust.Shared.Utility;
-using System.Diagnostics.CodeAnalysis;
-
-namespace Content.Server.DeviceNetwork
-{
-    public sealed class NetworkPayload : Dictionary<string, object?>
-    {
-        /// <summary>
-        /// Tries to get a value from the payload and checks if that value is of type  T.
-        /// </summary>
-        /// <typeparam name="T">The type that should be casted to</typeparam>
-        /// <returns>Whether the value was present in the payload and of the required type</returns>
-        public bool TryGetValue<T>(string key, [NotNullWhen(true)] out T? value)
-        {
-            if (this.TryCastValue(key, out T? result))
-            {
-                value = result;
-                return true;
-            }
-
-            value = default;
-            return false;
-        }
-    }
-
-}
index 11dc628df1ce0b3db33a50561a7bf0a52c75c124..9a4a81a4c0ad0666373c55f512823b4717a9adec 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Server.DeviceNetwork.Components;
 using Content.Server.DeviceNetwork.Components.Devices;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Interaction;
 
 namespace Content.Server.DeviceNetwork.Systems.Devices
index 1a819ab0fb186d790b60203cca3617324ed74ee1..001abad3dcd9264f6aa74e9d7869845e4103974e 100644 (file)
@@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork.Components;
 using Content.Server.DeviceNetwork.Systems;
 using Content.Server.Disposal.Unit.EntitySystems;
 using Content.Server.Power.Components;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Disposal;
 using Content.Shared.Interaction;
 using Robust.Server.GameObjects;
index f25fb6254257750e8811bd54665402028ce5a1a3..5fee750c1d93a2dcfe704401a768fbfe3c909b9e 100644 (file)
@@ -12,6 +12,7 @@ using Content.Shared.UserInterface;
 using Content.Shared.Administration.Logs;
 using Content.Shared.Containers.ItemSlots;
 using Content.Shared.Database;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Emag.Components;
 using Content.Shared.Emag.Systems;
 using Content.Shared.Fax;
index 785ef60af90b4b368491b6b253435dc105d1a22f..bff7f1565a16f57068d61ffe627f2e48492c6595 100644 (file)
@@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork.Systems;
 using Content.Server.Medical.SuitSensors;
 using Content.Server.Power.Components;
 using Content.Server.Station.Systems;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Medical.SuitSensor;
 using Robust.Shared.Timing;
 
index aa6dca718d5228b098a9858dd74e516a8eaaae0b..38a7b0a4517be3dfc8433d50db7fc9a69e460f71 100644 (file)
@@ -8,6 +8,7 @@ using Content.Server.Medical.CrewMonitoring;
 using Content.Server.Popups;
 using Content.Server.Station.Systems;
 using Content.Shared.Damage;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Emp;
 using Content.Shared.Examine;
 using Content.Shared.Inventory.Events;
index 54f40a1bf34fa4589aecb2a37a474e6e778cb9f0..3510a3da45de7f89bc3c13b44d1b509db183415b 100644 (file)
@@ -7,6 +7,7 @@ using Content.Server.DeviceNetwork.Systems;
 using Content.Server.NodeContainer;
 using Content.Server.NodeContainer.Nodes;
 using Content.Server.Power.Components;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Examine;
 using Content.Shared.Power.Generation.Teg;
 using Content.Shared.Rounding;
index 10d4bea8b540537ffe663aeb0eb03280eb7bf161..3a8331f3f7a68d3522be332224e70da75231d281 100644 (file)
@@ -14,6 +14,7 @@ using Content.Server.Shuttles.Systems;
 using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Shared.Database;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.GameTicking;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Configuration;
index 20e990b14c303ba0671e9639aba0eb4efe2ad1f2..eb2ab21075ce72451408e2fed7c7cb3760a0adc4 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Systems;
 using Content.Server.Power.Components;
+using Content.Shared.DeviceNetwork;
 
 namespace Content.Server.SensorMonitoring;
 
index fdd340ba0ae74e0fa30f5842e03146ffc2ab825b..ddd7812394ee05c003b6e150d908a84a512ac0b2 100644 (file)
@@ -10,13 +10,13 @@ using Content.Server.Power.Generation.Teg;
 using Content.Shared.Atmos.Monitor;
 using Content.Shared.Atmos.Piping.Binary.Components;
 using Content.Shared.Atmos.Piping.Unary.Components;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.DeviceNetwork.Components;
 using Content.Shared.DeviceNetwork.Systems;
 using Content.Shared.SensorMonitoring;
 using Robust.Server.GameObjects;
 using Robust.Shared.Timing;
 using Robust.Shared.Utility;
-using ConsoleUIState = Content.Shared.SensorMonitoring.SensorMonitoringConsoleBoundInterfaceState;
 
 namespace Content.Server.SensorMonitoring;
 
index 6503e4bf517d3db8d2447ae73c016a5f3984072e..08f3481cd72d083b5f6081e67a81a4b12f00d9f1 100644 (file)
@@ -16,6 +16,7 @@ using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Shared.Administration;
 using Content.Shared.CCVar;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Mobs.Components;
 using Content.Shared.Movement.Components;
 using Content.Shared.Parallax.Biomes;
index 37c70c4e486e544e7a32ac425110224a8cb81a09..b589a526403d5340463cd00e48fa68dd000bb68d 100644 (file)
@@ -8,6 +8,7 @@ using Content.Shared.UserInterface;
 using Content.Shared.Access;
 using Content.Shared.CCVar;
 using Content.Shared.Database;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Popups;
 using Content.Shared.Shuttles.BUIStates;
 using Content.Shared.Shuttles.Events;
index d984c727376dd641022486f8c69bb3c647a496cd..d9ba2de3e590eb59e78480eab8585a79bb36f003 100644 (file)
@@ -5,7 +5,6 @@ using Content.Server.Administration.Logs;
 using Content.Server.Administration.Managers;
 using Content.Server.Chat.Systems;
 using Content.Server.Communications;
-using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Components;
 using Content.Server.DeviceNetwork.Systems;
 using Content.Server.GameTicking.Events;
@@ -19,6 +18,7 @@ using Content.Server.Station.Systems;
 using Content.Shared.Access.Systems;
 using Content.Shared.CCVar;
 using Content.Shared.Database;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Shuttles.Components;
 using Content.Shared.Shuttles.Events;
 using Content.Shared.Tag;
index cbc2f6d31ec3642b6d969f62fdfc72574a9d7209..f258fbe89cf67ae3e68447c1e9d5049c47fcdab4 100644 (file)
@@ -2,6 +2,7 @@ using System.Linq;
 using Content.Server.DeviceNetwork;
 using Content.Server.DeviceNetwork.Systems;
 using Content.Server.Power.Components;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.UserInterface;
 using Content.Shared.SurveillanceCamera;
 using Robust.Server.GameObjects;
diff --git a/Content.Shared/DeviceLinking/Components/TwoWayLeverComponent.cs b/Content.Shared/DeviceLinking/Components/TwoWayLeverComponent.cs
new file mode 100644 (file)
index 0000000..6dfc255
--- /dev/null
@@ -0,0 +1,26 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.DeviceLinking.Components;
+
+/// <summary>
+/// Simple ternary state for device linking.
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class TwoWayLeverComponent : Component
+{
+    [DataField, AutoNetworkedField]
+    public TwoWayLeverState State;
+
+    [DataField, AutoNetworkedField]
+    public bool NextSignalLeft;
+
+    [DataField]
+    public ProtoId<SourcePortPrototype> LeftPort = "Left";
+
+    [DataField]
+    public ProtoId<SourcePortPrototype> RightPort = "Right";
+
+    [DataField]
+    public ProtoId<SourcePortPrototype> MiddlePort = "Middle";
+}
index 02c0f608532f0a245ea0870b67148b5212d376cb..9610e2e606599e24804a1e0cf0c9ff8880e08cb2 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Shared.Administration.Logs;
 using Content.Shared.Database;
 using Content.Shared.DeviceLinking.Events;
+using Content.Shared.DeviceNetwork;
 using Content.Shared.Popups;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Utility;
@@ -148,6 +149,9 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
     /// </summary>
     public void EnsureSourcePorts(EntityUid uid, params string[] ports)
     {
+        if (ports.Length == 0)
+            return;
+
         var comp = EnsureComp<DeviceLinkSourceComponent>(uid);
         comp.Ports ??= new HashSet<string>();
 
@@ -163,6 +167,9 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
     /// </summary>
     public void EnsureSinkPorts(EntityUid uid, params string[] ports)
     {
+        if (ports.Length == 0)
+            return;
+
         var comp = EnsureComp<DeviceLinkSinkComponent>(uid);
         comp.Ports ??= new HashSet<string>();
 
@@ -550,4 +557,20 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
                 ("machine2", sinkUid), ("port2", PortName<SinkPortPrototype>(sink))), userId.Value, PopupType.Medium);
     }
     #endregion
+
+    #region Sending & Receiving
+    /// <summary>
+    /// Sends a network payload directed at the sink entity.
+    /// Just raises a <see cref="SignalReceivedEvent"/> without data if the source or the sink doesn't have a <see cref="DeviceNetworkComponent"/>
+    /// </summary>
+    /// <param name="uid">The source uid that invokes the port</param>
+    /// <param name="port">The port to invoke</param>
+    /// <param name="data">Optional data to send along</param>
+    /// <param name="sourceComponent"></param>
+    public virtual void InvokePort(EntityUid uid, string port, NetworkPayload? data = null,
+        DeviceLinkSourceComponent? sourceComponent = null)
+    {
+        // NOOP on client for the moment.
+    }
+    #endregion
 }
similarity index 95%
rename from Content.Server/DeviceLinking/Systems/TwoWayLeverSystem.cs
rename to Content.Shared/DeviceLinking/Systems/TwoWayLeverSystem.cs
index 7d351dcac563809cc2374be4bfcf82ee0323b453..c8783b05fc706d3a5d265eb465473f3ef85d5abb 100644 (file)
@@ -1,14 +1,13 @@
-using Content.Server.DeviceLinking.Components;
-using Content.Shared.DeviceLinking;
+using Content.Shared.DeviceLinking.Components;
 using Content.Shared.Interaction;
 using Content.Shared.Verbs;
 using Robust.Shared.Utility;
 
-namespace Content.Server.DeviceLinking.Systems
+namespace Content.Shared.DeviceLinking.Systems
 {
     public sealed class TwoWayLeverSystem : EntitySystem
     {
-        [Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
+        [Dependency] private readonly SharedDeviceLinkSystem _signalSystem = default!;
         [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
 
         const string _leftToggleImage = "rotate_ccw.svg.192dpi.png";
@@ -111,6 +110,7 @@ namespace Content.Server.DeviceLinking.Systems
                 _ => throw new ArgumentOutOfRangeException()
             };
 
+            Dirty(uid, component);
             _signalSystem.InvokePort(uid, port);
         }
     }
diff --git a/Content.Shared/DeviceNetwork/NetworkPayload.cs b/Content.Shared/DeviceNetwork/NetworkPayload.cs
new file mode 100644 (file)
index 0000000..3239374
--- /dev/null
@@ -0,0 +1,24 @@
+using System.Diagnostics.CodeAnalysis;
+using Robust.Shared.Utility;
+
+namespace Content.Shared.DeviceNetwork;
+
+public sealed class NetworkPayload : Dictionary<string, object?>
+{
+    /// <summary>
+    /// Tries to get a value from the payload and checks if that value is of type  T.
+    /// </summary>
+    /// <typeparam name="T">The type that should be casted to</typeparam>
+    /// <returns>Whether the value was present in the payload and of the required type</returns>
+    public bool TryGetValue<T>(string key, [NotNullWhen(true)] out T? value)
+    {
+        if (this.TryCastValue(key, out T? result))
+        {
+            value = result;
+            return true;
+        }
+
+        value = default;
+        return false;
+    }
+}