using System.Linq; using Content.Server.DeviceNetwork.Components; using Content.Shared.DeviceNetwork; using Content.Shared.DeviceNetwork.Components; using Content.Shared.Interaction; using JetBrains.Annotations; namespace Content.Server.DeviceNetwork.Systems; [UsedImplicitly] public sealed class DeviceListSystem : SharedDeviceListSystem { public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnBeforeBroadcast); SubscribeLocalEvent(OnBeforePacketSent); } public void OnInit(EntityUid uid, DeviceListComponent component, ComponentInit args) { Dirty(component); } /// /// Gets the given device list as a dictionary /// /// /// If any entity in the device list is pre-map init, it will show the entity UID of the device instead. /// public Dictionary GetDeviceList(EntityUid uid, DeviceListComponent? deviceList = null) { if (!Resolve(uid, ref deviceList)) return new Dictionary(); var devices = new Dictionary(deviceList.Devices.Count); foreach (var deviceUid in deviceList.Devices) { if (!TryComp(deviceUid, out DeviceNetworkComponent? deviceNet)) continue; var address = MetaData(deviceUid).EntityLifeStage == EntityLifeStage.MapInitialized ? deviceNet.Address : $"UID: {deviceUid.ToString()}"; devices.Add(address, deviceUid); } return devices; } /// /// Filters the broadcasts recipient list against the device list as either an allow or deny list depending on the components IsAllowList field /// private void OnBeforeBroadcast(EntityUid uid, DeviceListComponent component, BeforeBroadcastAttemptEvent args) { //Don't filter anything if the device list is empty if (component.Devices.Count == 0) { if (component.IsAllowList) args.Cancel(); return; } HashSet filteredRecipients = new(args.Recipients.Count); foreach (var recipient in args.Recipients) { if (component.Devices.Contains(recipient.Owner) == component.IsAllowList) filteredRecipients.Add(recipient); } args.ModifiedRecipients = filteredRecipients; } /// /// Filters incoming packets if that is enabled /// private void OnBeforePacketSent(EntityUid uid, DeviceListComponent component, BeforePacketSentEvent args) { if (component.HandleIncomingPackets && component.Devices.Contains(args.Sender) != component.IsAllowList) args.Cancel(); } }