using Content.Shared.DeviceNetwork; using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Events; using JetBrains.Annotations; namespace Content.Server.DeviceNetwork.Systems; public sealed partial class DeviceNetworkSystem { [PublicAPI] public override bool SendPacket( Entity ent, string? address, ref T data, uint? frequency = null, int? network = null) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return false; var device = ent.Comp; if (device.Address == string.Empty) return false; frequency ??= device.TransmitFrequency; if (frequency == null) return false; network ??= device.DeviceNetId; var packet = new DeviceNetworkPacketEvent(network.Value, address, frequency.Value, device.Address, ent!, data); SendPacket(ref packet); return true; } /// /// Connect an entity with a DeviceNetworkComponent. Note that this will re-use an existing address if the /// device already had one configured. If there is a clash, the device cannot join the network. /// [PublicAPI] public bool ConnectDevice(Entity ent) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return false; if (!TryEnsureNetwork(ent.Comp.DeviceNetId, out var deviceNet)) return false; var success = deviceNet.Add(ent!); Dirty(ent); return success; } /// /// Disconnect an entity with a DeviceNetworkComponent. /// /// The entity to disconnect from its network. /// /// If true, sets to false. /// That way the device doesn't auto reconnect when a game state is loaded. /// /// True if the device was removed from the network successfully. [PublicAPI] public bool DisconnectDevice(Entity ent, bool preventAutoConnect = true) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return false; if (!TryGetNetwork(ent.Comp.DeviceNetId, out var deviceNet)) return false; if (preventAutoConnect) ent.Comp.AutoConnect = false; var result = deviceNet.Remove(ent!); return result; } /// /// Checks if a device is already connected to its network. /// /// True if the device was found in the network with its corresponding network id. [PublicAPI] public bool IsDeviceConnected(Entity ent) { var (uid, deviceComp) = ent; if (!_deviceQuery.Resolve(uid, ref deviceComp, false)) return false; if (!_networks.TryGetValue(deviceComp.DeviceNetId, out var deviceNet)) return false; var device = new Device(ent!); return deviceNet.Devices.ContainsValue(device); } /// /// Checks if an address exists in the network with the given netId. /// [PublicAPI] public bool IsAddressPresent(int netId, string? address) { if (address == null || !_networks.TryGetValue(netId, out var network)) return false; return network.Devices.ContainsKey(address); } /// /// Sets the receive frequency of an entity. /// /// The target device. /// The new frequency. [PublicAPI] public void SetReceiveFrequency(Entity ent, uint? frequency) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return; if (ent.Comp.ReceiveFrequency == frequency) return; if (!TryGetNetwork(ent.Comp.DeviceNetId, out var deviceNet)) return; var oldFrequency = ent.Comp.ReceiveFrequency; deviceNet.Remove(ent!); ent.Comp.ReceiveFrequency = frequency; deviceNet.Add(ent!); var ev = new DeviceReceiveFrequencyChangedEvent(oldFrequency, frequency); RaiseLocalEvent(ent, ref ev); Dirty(ent); } /// /// Sets the transmit frequency of an entity. /// /// The target device. /// The new frequency. [PublicAPI] public void SetTransmitFrequency(Entity ent, uint? frequency) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return; var oldFrequency = ent.Comp.TransmitFrequency; ent.Comp.TransmitFrequency = frequency; var ev = new DeviceReceiveFrequencyChangedEvent(oldFrequency, frequency); RaiseLocalEvent(ent, ref ev); } /// /// Sets the target device's ability to receive all network packets, regardless of the address. /// [PublicAPI] public void SetReceiveAll(Entity ent, bool receiveAll) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return; if (ent.Comp.ReceiveAll == receiveAll) return; if (!TryGetNetwork(ent.Comp.DeviceNetId, out var deviceNet)) return; deviceNet.Remove(ent!); ent.Comp.ReceiveAll = receiveAll; deviceNet.Add(ent!); var ev = new DeviceReceiveAllChangedEvent(receiveAll); RaiseLocalEvent(ent, ref ev); Dirty(ent); } /// /// Sets the address of the target device. /// [PublicAPI] public void SetAddress(Entity ent, string address) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return; if (ent.Comp.Address == address && ent.Comp.CustomAddress) return; if (!TryGetNetwork(ent.Comp.DeviceNetId, out var deviceNet)) return; var oldAddress = ent.Comp.Address; deviceNet.Remove(ent!); ent.Comp.CustomAddress = true; ent.Comp.Address = address; deviceNet.Add(ent!); var ev = new DeviceAddressChangedEvent(oldAddress, address, ent.Comp.CustomAddress); RaiseLocalEvent(ent, ref ev); Dirty(ent); } /// /// Randomizes the address of the target device. /// [PublicAPI] public void RandomizeAddress(Entity ent) { if (!_deviceQuery.Resolve(ent.Owner, ref ent.Comp, false)) return; if (!TryGetNetwork(ent.Comp.DeviceNetId, out var deviceNet)) return; var oldAddress = ent.Comp.Address; deviceNet.Remove(ent!); ent.Comp.CustomAddress = false; ent.Comp.Address = ""; deviceNet.Add(ent!); var ev = new DeviceAddressChangedEvent(oldAddress, ent.Comp.Address, ent.Comp.CustomAddress); RaiseLocalEvent(ent, ref ev); Dirty(ent); } }