From 83d29ce38d7744847c97bfd86bbe78fe1d46d16a Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Mon, 31 Jan 2022 04:26:07 +1300 Subject: [PATCH] Raise an attempt-event when receiving client BUI messages. (#6113) --- .../Unary/EntitySystems/GasCanisterSystem.cs | 19 --------- .../UserInterface/ActivatableUISystem.cs | 42 +++++++++---------- .../Interaction/SharedInteractionSystem.cs | 25 +++++++++++ Resources/Locale/en-US/ui/verbs.ftl | 2 + 4 files changed, 47 insertions(+), 41 deletions(-) create mode 100644 Resources/Locale/en-US/ui/verbs.ftl diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs index 7a98a2d9f8..7f0352547f 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs @@ -79,16 +79,6 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems } } - private bool CheckInteract(ICommonSession session) - { - if (session.AttachedEntity is not {Valid: true} uid - || !_actionBlockerSystem.CanInteract(uid) - || !_actionBlockerSystem.CanUse(uid)) - return false; - - return true; - } - private void DirtyUI(EntityUid uid, GasCanisterComponent? canister = null, NodeContainerComponent? nodeContainer = null, ContainerManagerComponent? containerManager = null) @@ -120,9 +110,6 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems private void OnHoldingTankEjectMessage(EntityUid uid, GasCanisterComponent canister, GasCanisterHoldingTankEjectMessage args) { - if (!CheckInteract(args.Session)) - return; - if (!EntityManager.TryGetComponent(uid, out ContainerManagerComponent? containerManager) || !containerManager.TryGetContainer(canister.ContainerName, out var container)) return; @@ -136,9 +123,6 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems private void OnCanisterChangeReleasePressure(EntityUid uid, GasCanisterComponent canister, GasCanisterChangeReleasePressureMessage args) { - if (!CheckInteract(args.Session)) - return; - var pressure = Math.Clamp(args.Pressure, canister.MinReleasePressure, canister.MaxReleasePressure); _adminLogSystem.Add(LogType.CanisterPressure, LogImpact.Medium, $"{ToPrettyString(args.Session.AttachedEntity.GetValueOrDefault()):player} set the release pressure on {ToPrettyString(uid):canister} to {args.Pressure}"); @@ -149,9 +133,6 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems private void OnCanisterChangeReleaseValve(EntityUid uid, GasCanisterComponent canister, GasCanisterChangeReleaseValveMessage args) { - if (!CheckInteract(args.Session)) - return; - var impact = LogImpact.High; if (EntityManager.TryGetComponent(uid, out ContainerManagerComponent containerManager) && containerManager.TryGetContainer(canister.ContainerName, out var container)) diff --git a/Content.Server/UserInterface/ActivatableUISystem.cs b/Content.Server/UserInterface/ActivatableUISystem.cs index 5cbabd3eb3..f64dca4648 100644 --- a/Content.Server/UserInterface/ActivatableUISystem.cs +++ b/Content.Server/UserInterface/ActivatableUISystem.cs @@ -1,9 +1,11 @@ using System.Linq; using Content.Server.Administration.Managers; +using Content.Server.Ghost.Components; using Content.Shared.ActionBlocker; using Content.Shared.Hands; using Content.Shared.Interaction; using Content.Shared.Popups; +using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Player; @@ -30,6 +32,23 @@ namespace Content.Server.UserInterface // *THIS IS A BLATANT WORKAROUND!* RATIONALE: Microwaves need it SubscribeLocalEvent(OnParentChanged); SubscribeLocalEvent(OnUIClose); + + SubscribeLocalEvent(AddOpenUiVerb); + } + + private void AddOpenUiVerb(EntityUid uid, ActivatableUIComponent component, GetActivationVerbsEvent args) + { + if (!args.CanAccess) + return; + + if (!args.CanInteract && !HasComp(args.User)) + return; + + Verb verb = new(); + verb.Act = () => InteractUI(args.User, component); + verb.Text = Loc.GetString("ui-verb-toggle-open"); + // TODO VERBS add "open UI" icon? + args.Verbs.Add(verb); } private void OnActivate(EntityUid uid, ActivatableUIComponent component, ActivateInWorldEvent args) @@ -63,7 +82,7 @@ namespace Content.Server.UserInterface if (aui.AdminOnly && !_adminManager.IsAdmin(actor.PlayerSession)) return false; - if (!_actionBlockerSystem.CanInteract(user)) + if (!HasComp(user) && !_actionBlockerSystem.CanInteract(user)) { user.PopupMessageCursor(Loc.GetString("base-computer-ui-component-cannot-interact")); return true; @@ -103,27 +122,6 @@ namespace Content.Server.UserInterface RaiseLocalEvent(uid, new ActivatableUIPlayerChangedEvent(), false); } - public override void Update(float frameTime) - { - base.Update(frameTime); - - foreach (var component in EntityManager.EntityQuery(true)) - { - var ui = component.UserInterface; - if (ui == null) continue; - // Done to skip an allocation on anything that's not in use. - if (ui.SubscribedSessions.Count == 0) continue; - // Must ToList in order to close things safely. - foreach (var session in ui.SubscribedSessions.ToArray()) - { - if (session.AttachedEntity == null || !_actionBlockerSystem.CanInteract(session.AttachedEntity.Value)) - { - ui.Close(session); - } - } - } - } - public void CloseAll(EntityUid uid, ActivatableUIComponent? aui = null) { if (!Resolve(uid, ref aui, false)) return; diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 3ed5f9d5db..09cfd1cde2 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -50,6 +50,7 @@ namespace Content.Shared.Interaction public override void Initialize() { + SubscribeLocalEvent(OnBoundInterfaceInteractAttempt); SubscribeAllEvent(HandleInteractInventorySlotEvent); CommandBinds.Builder @@ -64,6 +65,30 @@ namespace Content.Shared.Interaction base.Shutdown(); } + /// + /// Check that the user that is interacting with the BUI is capable of interacting and can access the entity. + /// + private void OnBoundInterfaceInteractAttempt(BoundUserInterfaceMessageAttempt ev) + { + if (ev.Sender.AttachedEntity is not EntityUid user || !_actionBlockerSystem.CanInteract(user)) + { + ev.Cancel(); + return; + } + + if (!user.IsInSameOrParentContainer(ev.Target) && !CanAccessViaStorage(user, ev.Target)) + { + ev.Cancel(); + return; + } + + if (!user.InRangeUnobstructed(ev.Target)) + { + ev.Cancel(); + return; + } + } + /// /// Handles the event were a client uses an item in their inventory or in their hands, either by /// alt-clicking it or pressing 'E' while hovering over it. diff --git a/Resources/Locale/en-US/ui/verbs.ftl b/Resources/Locale/en-US/ui/verbs.ftl new file mode 100644 index 0000000000..03ac42418b --- /dev/null +++ b/Resources/Locale/en-US/ui/verbs.ftl @@ -0,0 +1,2 @@ +### Loc for the various UI-related verbs +ui-verb-toggle-open = Toggle UI