Predict two-way levers (#25043)

* 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
This commit is contained in:
metalgearsloth
2024-02-11 14:19:45 +11:00
committed by GitHub
parent 8e59b4f505
commit 05a2ddff1c
35 changed files with 114 additions and 68 deletions

View File

@@ -4,8 +4,8 @@ using BenchmarkDotNet.Attributes;
using Content.IntegrationTests; using Content.IntegrationTests;
using Content.IntegrationTests.Pair; using Content.IntegrationTests.Pair;
using Content.IntegrationTests.Tests.DeviceNetwork; using Content.IntegrationTests.Tests.DeviceNetwork;
using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Systems; using Content.Server.DeviceNetwork.Systems;
using Content.Shared.DeviceNetwork;
using Robust.Shared; using Robust.Shared;
using Robust.Shared.Analyzers; using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;

View File

@@ -0,0 +1,8 @@
using Content.Shared.DeviceLinking;
namespace Content.Client.DeviceLinking;
public sealed class DeviceLinkSystem : SharedDeviceLinkSystem
{
}

View File

@@ -2,6 +2,7 @@ using System.Numerics;
using Content.Server.DeviceNetwork; 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.Shared.DeviceNetwork;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Map; using Robust.Shared.Map;

View File

@@ -1,7 +1,6 @@
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.Shared.DeviceNetwork;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Reflection; using Robust.Shared.Reflection;

View File

@@ -15,6 +15,7 @@ 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.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Systems; using Content.Shared.DeviceNetwork.Systems;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Wires; using Content.Shared.Wires;

View File

@@ -6,6 +6,7 @@ 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.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor;
using Content.Shared.DeviceNetwork;
using Content.Shared.Tag; using Content.Shared.Tag;
using Robust.Server.Audio; using Robust.Server.Audio;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;

View File

@@ -1,6 +1,7 @@
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Systems; using Content.Server.DeviceNetwork.Systems;
using Content.Shared.Atmos.Monitor.Components; using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.DeviceNetwork;
namespace Content.Server.Atmos.Monitor.Systems; namespace Content.Server.Atmos.Monitor.Systems;

View File

@@ -8,6 +8,7 @@ using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor;
using Content.Shared.DeviceNetwork;
using Content.Shared.Tag; using Content.Shared.Tag;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;

View File

@@ -13,6 +13,7 @@ using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.Atmos.Visuals; using Content.Shared.Atmos.Visuals;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Popups; using Content.Shared.Popups;

View File

@@ -17,6 +17,7 @@ using Content.Server.Power.EntitySystems;
using Content.Shared.UserInterface; using Content.Shared.UserInterface;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Examine; using Content.Shared.Examine;
namespace Content.Server.Atmos.Piping.Unary.EntitySystems namespace Content.Server.Atmos.Piping.Unary.EntitySystems

View File

@@ -16,6 +16,7 @@ using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Atmos.Visuals; using Content.Shared.Atmos.Visuals;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.DeviceNetwork;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Tools.Systems; using Content.Shared.Tools.Systems;
using JetBrains.Annotations; using JetBrains.Annotations;

View File

@@ -15,6 +15,7 @@ using Content.Shared.Atmos.Piping.Unary.Visuals;
using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.DeviceNetwork;
using Content.Shared.Tools.Systems; using Content.Shared.Tools.Systems;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;

View File

@@ -19,6 +19,7 @@ using Content.Shared.CCVar;
using Content.Shared.Chat; using Content.Shared.Chat;
using Content.Shared.Communications; using Content.Shared.Communications;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Emag.Components; using Content.Shared.Emag.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;

View File

@@ -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";
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Shared.DeviceNetwork;
namespace Content.Server.DeviceLinking.Events; namespace Content.Server.DeviceLinking.Events;

View File

@@ -4,6 +4,7 @@ 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.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.DeviceNetwork;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;
@@ -35,15 +36,7 @@ public sealed class DeviceLinkSystem : SharedDeviceLinkSystem
} }
#region Sending & Receiving #region Sending & Receiving
/// <summary> public override void InvokePort(EntityUid uid, string port, NetworkPayload? data = null, DeviceLinkSourceComponent? sourceComponent = null)
/// 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)
{ {
if (!Resolve(uid, ref sourceComponent) || !sourceComponent.Outputs.TryGetValue(port, out var sinks)) if (!Resolve(uid, ref sourceComponent) || !sourceComponent.Outputs.TryGetValue(port, out var sinks))
return; return;

View File

@@ -1,6 +1,7 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Server.Doors.Systems; using Content.Server.Doors.Systems;
using Content.Shared.DeviceNetwork;
using Content.Shared.Doors.Components; using Content.Shared.Doors.Components;
using Content.Shared.Doors; using Content.Shared.Doors;
using JetBrains.Annotations; using JetBrains.Annotations;

View File

@@ -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;
}
}
}

View File

@@ -1,5 +1,6 @@
using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Components.Devices; using Content.Server.DeviceNetwork.Components.Devices;
using Content.Shared.DeviceNetwork;
using Content.Shared.Interaction; using Content.Shared.Interaction;
namespace Content.Server.DeviceNetwork.Systems.Devices namespace Content.Server.DeviceNetwork.Systems.Devices

View File

@@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems; using Content.Server.DeviceNetwork.Systems;
using Content.Server.Disposal.Unit.EntitySystems; using Content.Server.Disposal.Unit.EntitySystems;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.Disposal; using Content.Shared.Disposal;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;

View File

@@ -12,6 +12,7 @@ using Content.Shared.UserInterface;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Emag.Components; using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems; using Content.Shared.Emag.Systems;
using Content.Shared.Fax; using Content.Shared.Fax;

View File

@@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork.Systems;
using Content.Server.Medical.SuitSensors; using Content.Server.Medical.SuitSensors;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.DeviceNetwork;
using Content.Shared.Medical.SuitSensor; using Content.Shared.Medical.SuitSensor;
using Robust.Shared.Timing; using Robust.Shared.Timing;

View File

@@ -8,6 +8,7 @@ using Content.Server.Medical.CrewMonitoring;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.DeviceNetwork;
using Content.Shared.Emp; using Content.Shared.Emp;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;

View File

@@ -7,6 +7,7 @@ using Content.Server.DeviceNetwork.Systems;
using Content.Server.NodeContainer; using Content.Server.NodeContainer;
using Content.Server.NodeContainer.Nodes; using Content.Server.NodeContainer.Nodes;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Power.Generation.Teg; using Content.Shared.Power.Generation.Teg;
using Content.Shared.Rounding; using Content.Shared.Rounding;

View File

@@ -14,6 +14,7 @@ using Content.Server.Shuttles.Systems;
using Content.Server.Station.Components; using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.GameTicking; using Content.Shared.GameTicking;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;

View File

@@ -1,6 +1,7 @@
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.Shared.DeviceNetwork;
namespace Content.Server.SensorMonitoring; namespace Content.Server.SensorMonitoring;

View File

@@ -10,13 +10,13 @@ using Content.Server.Power.Generation.Teg;
using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Atmos.Piping.Binary.Components;
using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Components;
using Content.Shared.DeviceNetwork.Systems; using Content.Shared.DeviceNetwork.Systems;
using Content.Shared.SensorMonitoring; using Content.Shared.SensorMonitoring;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using ConsoleUIState = Content.Shared.SensorMonitoring.SensorMonitoringConsoleBoundInterfaceState;
namespace Content.Server.SensorMonitoring; namespace Content.Server.SensorMonitoring;

View File

@@ -16,6 +16,7 @@ using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Administration; using Content.Shared.Administration;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.DeviceNetwork;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Content.Shared.Parallax.Biomes; using Content.Shared.Parallax.Biomes;

View File

@@ -8,6 +8,7 @@ using Content.Shared.UserInterface;
using Content.Shared.Access; using Content.Shared.Access;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.BUIStates;
using Content.Shared.Shuttles.Events; using Content.Shared.Shuttles.Events;

View File

@@ -5,7 +5,6 @@ using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers; using Content.Server.Administration.Managers;
using Content.Server.Chat.Systems; using Content.Server.Chat.Systems;
using Content.Server.Communications; using Content.Server.Communications;
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.GameTicking.Events; using Content.Server.GameTicking.Events;
@@ -19,6 +18,7 @@ using Content.Server.Station.Systems;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Components;
using Content.Shared.Shuttles.Events; using Content.Shared.Shuttles.Events;
using Content.Shared.Tag; using Content.Shared.Tag;

View File

@@ -2,6 +2,7 @@ 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.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;

View File

@@ -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";
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceLinking.Events; using Content.Shared.DeviceLinking.Events;
using Content.Shared.DeviceNetwork;
using Content.Shared.Popups; using Content.Shared.Popups;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -148,6 +149,9 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
/// </summary> /// </summary>
public void EnsureSourcePorts(EntityUid uid, params string[] ports) public void EnsureSourcePorts(EntityUid uid, params string[] ports)
{ {
if (ports.Length == 0)
return;
var comp = EnsureComp<DeviceLinkSourceComponent>(uid); var comp = EnsureComp<DeviceLinkSourceComponent>(uid);
comp.Ports ??= new HashSet<string>(); comp.Ports ??= new HashSet<string>();
@@ -163,6 +167,9 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
/// </summary> /// </summary>
public void EnsureSinkPorts(EntityUid uid, params string[] ports) public void EnsureSinkPorts(EntityUid uid, params string[] ports)
{ {
if (ports.Length == 0)
return;
var comp = EnsureComp<DeviceLinkSinkComponent>(uid); var comp = EnsureComp<DeviceLinkSinkComponent>(uid);
comp.Ports ??= new HashSet<string>(); comp.Ports ??= new HashSet<string>();
@@ -550,4 +557,20 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
("machine2", sinkUid), ("port2", PortName<SinkPortPrototype>(sink))), userId.Value, PopupType.Medium); ("machine2", sinkUid), ("port2", PortName<SinkPortPrototype>(sink))), userId.Value, PopupType.Medium);
} }
#endregion #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
} }

View File

@@ -1,14 +1,13 @@
using Content.Server.DeviceLinking.Components; using Content.Shared.DeviceLinking.Components;
using Content.Shared.DeviceLinking;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Server.DeviceLinking.Systems namespace Content.Shared.DeviceLinking.Systems
{ {
public sealed class TwoWayLeverSystem : EntitySystem public sealed class TwoWayLeverSystem : EntitySystem
{ {
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!; [Dependency] private readonly SharedDeviceLinkSystem _signalSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
const string _leftToggleImage = "rotate_ccw.svg.192dpi.png"; const string _leftToggleImage = "rotate_ccw.svg.192dpi.png";
@@ -111,6 +110,7 @@ namespace Content.Server.DeviceLinking.Systems
_ => throw new ArgumentOutOfRangeException() _ => throw new ArgumentOutOfRangeException()
}; };
Dirty(uid, component);
_signalSystem.InvokePort(uid, port); _signalSystem.InvokePort(uid, port);
} }
} }

View File

@@ -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;
}
}