| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- using Content.Server.Access.Systems;
- using Content.Server.AlertLevel;
- using Content.Server.CartridgeLoader;
- using Content.Server.Chat.Managers;
- using Content.Server.DeviceNetwork.Components;
- using Content.Server.Instruments;
- using Content.Server.Light.EntitySystems;
- using Content.Server.PDA.Ringer;
- using Content.Server.Station.Systems;
- using Content.Server.Store.Components;
- using Content.Server.Store.Systems;
- using Content.Server.Traitor.Uplink;
- using Content.Shared.Access.Components;
- using Content.Shared.CartridgeLoader;
- using Content.Shared.Chat;
- using Content.Shared.Light;
- using Content.Shared.Light.Components;
- using Content.Shared.Light.EntitySystems;
- using Content.Shared.PDA;
- using Content.Shared.Store.Components;
- using Robust.Server.Containers;
- using Robust.Server.GameObjects;
- using Robust.Shared.Containers;
- using Robust.Shared.Player;
- using Robust.Shared.Utility;
- namespace Content.Server.PDA
- {
- public sealed class PdaSystem : SharedPdaSystem
- {
- [Dependency] private readonly CartridgeLoaderSystem _cartridgeLoader = default!;
- [Dependency] private readonly InstrumentSystem _instrument = default!;
- [Dependency] private readonly RingerSystem _ringer = default!;
- [Dependency] private readonly StationSystem _station = default!;
- [Dependency] private readonly StoreSystem _store = default!;
- [Dependency] private readonly IChatManager _chatManager = default!;
- [Dependency] private readonly UserInterfaceSystem _ui = default!;
- [Dependency] private readonly UnpoweredFlashlightSystem _unpoweredFlashlight = default!;
- [Dependency] private readonly ContainerSystem _containerSystem = default!;
- [Dependency] private readonly IdCardSystem _idCard = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<PdaComponent, LightToggleEvent>(OnLightToggle);
- // UI Events:
- SubscribeLocalEvent<PdaComponent, BoundUIOpenedEvent>(OnPdaOpen);
- SubscribeLocalEvent<PdaComponent, PdaRequestUpdateInterfaceMessage>(OnUiMessage);
- SubscribeLocalEvent<PdaComponent, PdaToggleFlashlightMessage>(OnUiMessage);
- SubscribeLocalEvent<PdaComponent, PdaShowRingtoneMessage>(OnUiMessage);
- SubscribeLocalEvent<PdaComponent, PdaShowMusicMessage>(OnUiMessage);
- SubscribeLocalEvent<PdaComponent, PdaShowUplinkMessage>(OnUiMessage);
- SubscribeLocalEvent<PdaComponent, PdaLockUplinkMessage>(OnUiMessage);
- SubscribeLocalEvent<PdaComponent, CartridgeLoaderNotificationSentEvent>(OnNotification);
- SubscribeLocalEvent<StationRenamedEvent>(OnStationRenamed);
- SubscribeLocalEvent<EntityRenamedEvent>(OnEntityRenamed, after: new[] { typeof(IdCardSystem) });
- SubscribeLocalEvent<AlertLevelChangedEvent>(OnAlertLevelChanged);
- }
- private void OnEntityRenamed(ref EntityRenamedEvent ev)
- {
- if (HasComp<IdCardComponent>(ev.Uid))
- return;
- if (_idCard.TryFindIdCard(ev.Uid, out var idCard))
- {
- var query = EntityQueryEnumerator<PdaComponent>();
- while (query.MoveNext(out var uid, out var comp))
- {
- if (comp.ContainedId == idCard)
- {
- SetOwner(uid, comp, ev.Uid, ev.NewName);
- }
- }
- }
- }
- protected override void OnComponentInit(EntityUid uid, PdaComponent pda, ComponentInit args)
- {
- base.OnComponentInit(uid, pda, args);
- if (!HasComp<UserInterfaceComponent>(uid))
- return;
- UpdateAlertLevel(uid, pda);
- UpdateStationName(uid, pda);
- }
- protected override void OnItemInserted(EntityUid uid, PdaComponent pda, EntInsertedIntoContainerMessage args)
- {
- base.OnItemInserted(uid, pda, args);
- var id = CompOrNull<IdCardComponent>(pda.ContainedId);
- if (id != null)
- pda.OwnerName = id.FullName;
- UpdatePdaUi(uid, pda);
- }
- protected override void OnItemRemoved(EntityUid uid, PdaComponent pda, EntRemovedFromContainerMessage args)
- {
- if (args.Container.ID != pda.IdSlot.ID && args.Container.ID != pda.PenSlot.ID && args.Container.ID != pda.PaiSlot.ID)
- return;
- // TODO: This is super cursed just use compstates please.
- if (MetaData(uid).EntityLifeStage >= EntityLifeStage.Terminating)
- return;
- base.OnItemRemoved(uid, pda, args);
- UpdatePdaUi(uid, pda);
- }
- private void OnLightToggle(EntityUid uid, PdaComponent pda, LightToggleEvent args)
- {
- pda.FlashlightOn = args.IsOn;
- UpdatePdaUi(uid, pda);
- }
- public void SetOwner(EntityUid uid, PdaComponent pda, EntityUid owner, string ownerName)
- {
- pda.OwnerName = ownerName;
- pda.PdaOwner = owner;
- UpdatePdaUi(uid, pda);
- }
- private void OnStationRenamed(StationRenamedEvent ev)
- {
- UpdateAllPdaUisOnStation();
- }
- private void OnAlertLevelChanged(AlertLevelChangedEvent args)
- {
- UpdateAllPdaUisOnStation();
- }
- private void UpdateAllPdaUisOnStation()
- {
- var query = AllEntityQuery<PdaComponent>();
- while (query.MoveNext(out var ent, out var comp))
- {
- UpdatePdaUi(ent, comp);
- }
- }
- private void OnNotification(Entity<PdaComponent> ent, ref CartridgeLoaderNotificationSentEvent args)
- {
- _ringer.RingerPlayRingtone(ent.Owner);
- if (!_containerSystem.TryGetContainingContainer((ent, null, null), out var container)
- || !TryComp<ActorComponent>(container.Owner, out var actor))
- return;
- var message = FormattedMessage.EscapeText(args.Message);
- var wrappedMessage = Loc.GetString("pda-notification-message",
- ("header", args.Header),
- ("message", message));
- _chatManager.ChatMessageToOne(
- ChatChannel.Notifications,
- message,
- wrappedMessage,
- EntityUid.Invalid,
- false,
- actor.PlayerSession.Channel);
- }
- /// <summary>
- /// Send new UI state to clients, call if you modify something like uplink.
- /// </summary>
- public void UpdatePdaUi(EntityUid uid, PdaComponent? pda = null)
- {
- if (!Resolve(uid, ref pda, false))
- return;
- if (!_ui.HasUi(uid, PdaUiKey.Key))
- return;
- var address = GetDeviceNetAddress(uid);
- var hasInstrument = HasComp<InstrumentComponent>(uid);
- var showUplink = HasComp<UplinkComponent>(uid) && IsUnlocked(uid);
- UpdateStationName(uid, pda);
- UpdateAlertLevel(uid, pda);
- // TODO: Update the level and name of the station with each call to UpdatePdaUi is only needed for latejoin players.
- // TODO: If someone can implement changing the level and name of the station when changing the PDA grid, this can be removed.
- // TODO don't make this depend on cartridge loader!?!?
- if (!TryComp(uid, out CartridgeLoaderComponent? loader))
- return;
- var programs = _cartridgeLoader.GetAvailablePrograms(uid, loader);
- var id = CompOrNull<IdCardComponent>(pda.ContainedId);
- var state = new PdaUpdateState(
- programs,
- GetNetEntity(loader.ActiveProgram),
- pda.FlashlightOn,
- pda.PenSlot.HasItem,
- pda.PaiSlot.HasItem,
- new PdaIdInfoText
- {
- ActualOwnerName = pda.OwnerName,
- IdOwner = id?.FullName,
- JobTitle = id?.LocalizedJobTitle,
- StationAlertLevel = pda.StationAlertLevel,
- StationAlertColor = pda.StationAlertColor
- },
- pda.StationName,
- showUplink,
- hasInstrument,
- address);
- _ui.SetUiState(uid, PdaUiKey.Key, state);
- }
- private void OnPdaOpen(Entity<PdaComponent> ent, ref BoundUIOpenedEvent args)
- {
- if (!PdaUiKey.Key.Equals(args.UiKey))
- return;
- UpdatePdaUi(ent.Owner, ent.Comp);
- }
- private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaRequestUpdateInterfaceMessage msg)
- {
- if (!PdaUiKey.Key.Equals(msg.UiKey))
- return;
- UpdatePdaUi(uid, pda);
- }
- private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaToggleFlashlightMessage msg)
- {
- if (!PdaUiKey.Key.Equals(msg.UiKey))
- return;
- // TODO PREDICTION
- // When moving this to shared, fill in the user field
- _unpoweredFlashlight.TryToggleLight(uid, user: null);
- }
- private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowRingtoneMessage msg)
- {
- if (!PdaUiKey.Key.Equals(msg.UiKey))
- return;
- if (HasComp<RingerComponent>(uid))
- _ringer.ToggleRingerUI(uid, msg.Actor);
- }
- private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowMusicMessage msg)
- {
- if (!PdaUiKey.Key.Equals(msg.UiKey))
- return;
- if (TryComp<InstrumentComponent>(uid, out var instrument))
- _instrument.ToggleInstrumentUi(uid, msg.Actor, instrument);
- }
- private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaShowUplinkMessage msg)
- {
- if (!PdaUiKey.Key.Equals(msg.UiKey))
- return;
- // check if its locked again to prevent malicious clients opening locked uplinks
- if (HasComp<UplinkComponent>(uid) && IsUnlocked(uid))
- _store.ToggleUi(msg.Actor, uid);
- }
- private void OnUiMessage(EntityUid uid, PdaComponent pda, PdaLockUplinkMessage msg)
- {
- if (!PdaUiKey.Key.Equals(msg.UiKey))
- return;
- if (TryComp<RingerUplinkComponent>(uid, out var uplink))
- {
- _ringer.LockUplink(uid, uplink);
- UpdatePdaUi(uid, pda);
- }
- }
- private bool IsUnlocked(EntityUid uid)
- {
- return !TryComp<RingerUplinkComponent>(uid, out var uplink) || uplink.Unlocked;
- }
- private void UpdateStationName(EntityUid uid, PdaComponent pda)
- {
- var station = _station.GetOwningStation(uid);
- pda.StationName = station is null ? null : Name(station.Value);
- }
- private void UpdateAlertLevel(EntityUid uid, PdaComponent pda)
- {
- var station = _station.GetOwningStation(uid);
- if (!TryComp(station, out AlertLevelComponent? alertComp) ||
- alertComp.AlertLevels == null)
- return;
- pda.StationAlertLevel = alertComp.CurrentLevel;
- if (alertComp.AlertLevels.Levels.TryGetValue(alertComp.CurrentLevel, out var details))
- pda.StationAlertColor = details.Color;
- }
- private string? GetDeviceNetAddress(EntityUid uid)
- {
- string? address = null;
- if (TryComp(uid, out DeviceNetworkComponent? deviceNetworkComponent))
- {
- address = deviceNetworkComponent?.Address;
- }
- return address;
- }
- }
- }
|