using Content.Server.DeviceNetwork.Systems; using Content.Shared.DeviceNetwork.Events; using Robust.Shared.Timing; using Content.Shared.DeviceNetwork.Components; using Content.Shared.Medical.CrewMonitoring; using Content.Shared.Medical.SuitSensors; namespace Content.Server.Medical.CrewMonitoring; public sealed partial class CrewMonitoringServerSystem : EntitySystem { [Dependency] private IGameTiming _gameTiming = default!; [Dependency] private DeviceNetworkSystem _deviceNetworkSystem = default!; [Dependency] private SingletonDeviceNetServerSystem _singletonServerSystem = default!; private const float UpdateRate = 3f; private float _updateDiff; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnDisconnected); } public override void Update(float frameTime) { base.Update(frameTime); // check update rate _updateDiff += frameTime; if (_updateDiff < UpdateRate) return; _updateDiff -= UpdateRate; var servers = EntityQueryEnumerator(); while (servers.MoveNext(out var id, out var server)) { if (!_singletonServerSystem.IsActiveServer(id)) continue; UpdateTimeout(id); BroadcastSensorStatus(id, server); } } /// /// Adds or updates a sensor status entry if the received package is a sensor status update /// [SubscribeLocalEvent] private void OnSensorStatus(Entity ent, ref DeviceNetworkPacketEvent args) { var sensorData = args.Data.Data; sensorData.Timestamp = _gameTiming.CurTime; ent.Comp.SensorStatus[args.SenderAddress] = sensorData; } /// /// Clears the servers sensor status list /// private void OnRemove(EntityUid uid, CrewMonitoringServerComponent component, ComponentRemove args) { component.SensorStatus.Clear(); } /// /// Drop the sensor status if it hasn't been updated for to long /// private void UpdateTimeout(EntityUid uid, CrewMonitoringServerComponent? component = null) { if (!Resolve(uid, ref component)) return; foreach (var (address, sensor) in component.SensorStatus) { var dif = _gameTiming.CurTime - sensor.Timestamp; if (dif.Seconds > component.SensorTimeout) component.SensorStatus.Remove(address); } } /// /// Broadcasts the status of all connected sensors /// private void BroadcastSensorStatus(EntityUid uid, CrewMonitoringServerComponent? serverComponent = null, DeviceNetworkComponent? device = null) { if (!Resolve(uid, ref serverComponent, ref device)) return; var payload = new BroadcastSuitSensorStatePayload { SensorStatus = serverComponent.SensorStatus, }; _deviceNetworkSystem.SendPacket((uid, device), null, ref payload); } /// /// Clears sensor data on disconnect /// private void OnDisconnected(EntityUid uid, CrewMonitoringServerComponent component, ref DeviceNetServerDisconnectedEvent _) { component.SensorStatus.Clear(); } }