using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Events; using Content.Shared.DeviceNetwork.Payloads; using Content.Shared.SurveillanceCamera; namespace Content.Shared.DeviceNetwork.Systems; /// /// A system for re-routing s /// through an entity with . /// public sealed partial class DeviceNetworkRouterSystem : EntitySystem { [Dependency] private SharedDeviceNetworkSystem _deviceNetworkSystem = default!; [Dependency] private EntityQuery _query = default!; // TODO: make an engine PR to allow for auto-generated relay subscriptions // Should be doable by using reflection on marker interfaces and then adding them to the auto-generated subscriptions // I know it looks absolutely hilarious and horrible, but uuuhhhh anything to not make boxing allocations!!!!!!!! :godo: public override void Initialize() { base.Initialize(); // Surveillance cameras SubscribeLocalEvent>>((ent, ref args) => OnRoutePayload(ent, ref args)); SubscribeLocalEvent>>((ent, ref args) => OnRoutePayload(ent, ref args)); SubscribeLocalEvent>>((ent, ref args) => OnRoutePayload(ent, ref args)); SubscribeLocalEvent>>((ent, ref args) => OnRoutePayload(ent, ref args)); SubscribeLocalEvent>>((ent, ref args) => OnRoutePayload(ent, ref args)); SubscribeLocalEvent>>((ent, ref args) => OnRoutePayload(ent, ref args)); } private void OnRoutePayload(Entity ent, ref DeviceNetworkPacketEvent args) where T : IRoutedNetworkPayload { var payload = args.Data; if (!_query.TryComp(ent, out var deviceComp)) return; args.Data.Reroute(ent.Owner, payload.TargetAddress, payload.OverrideFrequency ?? deviceComp.TransmitFrequency, payload.OverrideNetwork ?? deviceComp.DeviceNetId, _deviceNetworkSystem); } /// /// Sends the given as a device network packet to the Relay entity with the given address and frequency. /// After the payload is received by an entity with , /// it gets re-routed to . /// /// /// This is useful for routing server setups where the packet must be sent in both directions through a server. /// /// The sending entity. /// The data to be sent. /// /// The address of the entity with that the packet gets sent to. /// If null, the message is broadcast to all devices on that frequency (except the sender). /// This address must include the router entity, so the packet can be relayed. /// /// /// The Actual address to which the payload will be relayed /// to after it was received by a . /// /// The frequency to send on to the router. /// If specified, will use this frequency when re-routing the packet. /// The network to send on to the router. /// If specified, will use this network when re-routing the packet. /// Returns true when the packet was successfully enqueued. public void SendPacketRouted( Entity ent, ref T data, string? routerAddress, string? targetAddress, uint? overrideFrequency = null, uint? frequency = null, int? overrideNetwork = null, int? network = null) where T : IRoutableNetworkPayload { if (!_query.Resolve(ref ent) || ent.Comp == null) return; data.SenderAddress = ent.Comp.Address; data.Sender = ent.Owner; var payload = new RoutedNetworkPayload { Payload = data, OverrideFrequency = overrideFrequency, OverrideNetwork = overrideNetwork, TargetAddress = targetAddress, }; _deviceNetworkSystem.SendPacket(ent.Owner, routerAddress, ref payload, frequency, network); } }