From 8c9c6dad823428fd58ace23e175245a2422d5ef9 Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Thu, 13 Nov 2025 00:10:48 +0100 Subject: [PATCH] Add keybinds for openening a specified component in VV (#41348) * quick inspect * Update Content.Client/Commands/QuickInspectCommand.cs Co-authored-by: Kyle Tyo <36606155+VerinSenpai@users.noreply.github.com> * documentation!!! --------- Co-authored-by: Kyle Tyo <36606155+VerinSenpai@users.noreply.github.com> --- .../Commands/QuickInspectCommand.cs | 52 +++++++++++++++++++ Content.Client/Gameplay/GameplayStateBase.cs | 20 +++++++ Content.Client/Input/ContentContexts.cs | 2 + .../Options/UI/Tabs/KeyRebindTab.xaml.cs | 2 + Content.Shared/CCVar/CCVars.Debug.cs | 13 +++++ Content.Shared/Input/ContentKeyFunctions.cs | 3 +- .../en-US/commands/quick-inspect-command.ftl | 5 ++ .../en-US/escape-menu/ui/options-menu.ftl | 5 ++ Resources/clientCommandPerms.yml | 1 + Resources/keybinds.yml | 8 +++ 10 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 Content.Client/Commands/QuickInspectCommand.cs create mode 100644 Content.Shared/CCVar/CCVars.Debug.cs create mode 100644 Resources/Locale/en-US/commands/quick-inspect-command.ftl diff --git a/Content.Client/Commands/QuickInspectCommand.cs b/Content.Client/Commands/QuickInspectCommand.cs new file mode 100644 index 0000000000..dc3aae615a --- /dev/null +++ b/Content.Client/Commands/QuickInspectCommand.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Content.Shared.CCVar; +using Content.Shared.Input; +using Robust.Client.Input; +using Robust.Shared.Configuration; +using Robust.Shared.Console; + +namespace Content.Client.Commands; + +/// +/// Sets the a CVar to the name of a component, which allows the client to quickly open a VV window for that component +/// by using the Alt+C or Alt+B hotkeys. +/// +public sealed class QuickInspectCommand : LocalizedEntityCommands +{ + [Dependency] private readonly IConfigurationManager _configurationManager = default!; + [Dependency] private readonly IInputManager _inputManager = default!; + + public override string Command => "quickinspect"; + + public override void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length != 1) + { + shell.WriteLine(Loc.GetString("shell-wrong-arguments-number")); + return; + } + + _configurationManager.SetCVar(CCVars.DebugQuickInspect, args[0]); + + var serverKey = _inputManager.GetKeyFunctionButtonString(ContentKeyFunctions.InspectServerComponent); + var clientKey = _inputManager.GetKeyFunctionButtonString(ContentKeyFunctions.InspectClientComponent); + shell.WriteLine(Loc.GetString($"cmd-quickinspect-success", ("component", args[0]), ("serverKeybind", serverKey), ("clientKeybind", clientKey))); + } + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + if (args.Length == 1) + { + // Not ideal since it only shows client-side components, but you can still type in any name you want. + // If you know how to get server component names on the client then please fix this. + var options = EntityManager.ComponentFactory.AllRegisteredTypes + .Select(p => new CompletionOption( + EntityManager.ComponentFactory.GetComponentName(p) + )); + + return CompletionResult.FromOptions(options); + } + + return CompletionResult.Empty; + } +} diff --git a/Content.Client/Gameplay/GameplayStateBase.cs b/Content.Client/Gameplay/GameplayStateBase.cs index 69e6e0b58b..c2b10fd01a 100644 --- a/Content.Client/Gameplay/GameplayStateBase.cs +++ b/Content.Client/Gameplay/GameplayStateBase.cs @@ -3,6 +3,7 @@ using System.Numerics; using Content.Client.Clickable; using Content.Client.UserInterface; using Content.Client.Viewport; +using Content.Shared.CCVar; using Content.Shared.Input; using Robust.Client.ComponentTrees; using Robust.Client.GameObjects; @@ -13,6 +14,7 @@ using Robust.Client.State; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; +using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Graphics; using Robust.Shared.Input; @@ -40,6 +42,7 @@ namespace Content.Client.Gameplay [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IViewVariablesManager _vvm = default!; [Dependency] private readonly IConsoleHost _conHost = default!; + [Dependency] private readonly IConfigurationManager _configurationManager = default!; private ClickableEntityComparer _comparer = default!; @@ -83,6 +86,8 @@ namespace Content.Client.Gameplay _comparer = new ClickableEntityComparer(); CommandBinds.Builder .Bind(ContentKeyFunctions.InspectEntity, new PointerInputCmdHandler(HandleInspect, outsidePrediction: true)) + .Bind(ContentKeyFunctions.InspectServerComponent, new PointerInputCmdHandler(HandleInspectServerComponent, outsidePrediction: true)) + .Bind(ContentKeyFunctions.InspectClientComponent, new PointerInputCmdHandler(HandleInspectClientComponent, outsidePrediction: true)) .Register(); } @@ -99,6 +104,21 @@ namespace Content.Client.Gameplay return true; } + private bool HandleInspectServerComponent(ICommonSession? session, EntityCoordinates coords, EntityUid uid) + { + var component = _configurationManager.GetCVar(CCVars.DebugQuickInspect); + if (_entityManager.TryGetNetEntity(uid, out var net)) + _conHost.ExecuteCommand($"vv /entity/{net.Value.Id}/{component}"); + return true; + } + + private bool HandleInspectClientComponent(ICommonSession? session, EntityCoordinates coords, EntityUid uid) + { + var component = _configurationManager.GetCVar(CCVars.DebugQuickInspect); + _conHost.ExecuteCommand($"vv /c/entity/{uid}/{component}"); + return true; + } + public EntityUid? GetClickedEntity(MapCoordinates coordinates) { return GetClickedEntity(coordinates, _eyeManager.CurrentEye); diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index 47f0cda2f6..01e7dc367c 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -38,6 +38,8 @@ namespace Content.Client.Input common.AddFunction(ContentKeyFunctions.ZoomIn); common.AddFunction(ContentKeyFunctions.ResetZoom); common.AddFunction(ContentKeyFunctions.InspectEntity); + common.AddFunction(ContentKeyFunctions.InspectServerComponent); + common.AddFunction(ContentKeyFunctions.InspectClientComponent); common.AddFunction(ContentKeyFunctions.ToggleRoundEndSummaryWindow); // Not in engine, because engine cannot check for sanbox/admin status before starting placement. diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index f92f66df31..40d1836c08 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -268,6 +268,8 @@ namespace Content.Client.Options.UI.Tabs AddButton(EngineKeyFunctions.ShowDebugMonitors); AddButton(EngineKeyFunctions.HideUI); AddButton(ContentKeyFunctions.InspectEntity); + AddButton(ContentKeyFunctions.InspectServerComponent); + AddButton(ContentKeyFunctions.InspectClientComponent); AddHeader("ui-options-header-text-cursor"); AddButton(EngineKeyFunctions.TextCursorLeft); diff --git a/Content.Shared/CCVar/CCVars.Debug.cs b/Content.Shared/CCVar/CCVars.Debug.cs new file mode 100644 index 0000000000..a95acc4dac --- /dev/null +++ b/Content.Shared/CCVar/CCVars.Debug.cs @@ -0,0 +1,13 @@ +using Robust.Shared.Configuration; + +namespace Content.Shared.CCVar; + +public sealed partial class CCVars +{ + /// + /// Component to be inspected using the "Quick Inspect Component" keybind. + /// Set by the "quickinspect" command. + /// + public static readonly CVarDef DebugQuickInspect = + CVarDef.Create("debug.quick_inspect", "", CVar.CLIENTONLY | CVar.ARCHIVE); +} diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs index 50ea218b00..63f6310322 100644 --- a/Content.Shared/Input/ContentKeyFunctions.cs +++ b/Content.Shared/Input/ContentKeyFunctions.cs @@ -123,7 +123,8 @@ namespace Content.Shared.Input public static readonly BoundKeyFunction EditorCopyObject = "EditorCopyObject"; public static readonly BoundKeyFunction EditorFlipObject = "EditorFlipObject"; public static readonly BoundKeyFunction InspectEntity = "InspectEntity"; - + public static readonly BoundKeyFunction InspectServerComponent = "InspectServerComponent"; + public static readonly BoundKeyFunction InspectClientComponent = "InspectClientComponent"; public static readonly BoundKeyFunction MappingUnselect = "MappingUnselect"; public static readonly BoundKeyFunction SaveMap = "SaveMap"; public static readonly BoundKeyFunction MappingEnablePick = "MappingEnablePick"; diff --git a/Resources/Locale/en-US/commands/quick-inspect-command.ftl b/Resources/Locale/en-US/commands/quick-inspect-command.ftl new file mode 100644 index 0000000000..e057fd982f --- /dev/null +++ b/Resources/Locale/en-US/commands/quick-inspect-command.ftl @@ -0,0 +1,5 @@ +cmd-quickinspect-desc = Sets a component name to be opened for a hovered entity via the "Inspect Server/Client Component" keybind. +cmd-quickinspect-help = Usage: {$command} +cmd-quickinspect-success = Component set to: {$component}. + Press {$serverKeybind} to open a VV window for the server. + Press {$clientKeybind} to open a VV window for the client. diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index 98ee2543c1..a263e52229 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -227,6 +227,11 @@ ui-options-function-editor-copy-object = Copy ui-options-function-show-debug-console = Open Console ui-options-function-show-debug-monitors = Show Debug Monitors ui-options-function-inspect-entity = Inspect Entity +ui-options-function-inspect-entity-tooltip = Open a ViewVariables window for the entity your mouse is currently hovering over. +ui-options-function-inspect-server-component = Inspect Server Component +ui-options-function-inspect-server-component-tooltip = Open a ViewVariables window with the server component set by the "quickinspect" command for the entity your mouse is currently hovering over. +ui-options-function-inspect-client-component = Inspect Client Component +ui-options-function-inspect-client-component-tooltip = Open a ViewVariables window with the client component set by the "quickinspect" command for the entity your mouse is currently hovering over. ui-options-function-hide-ui = Hide UI ui-options-function-hotbar1 = Hotbar slot 1 diff --git a/Resources/clientCommandPerms.yml b/Resources/clientCommandPerms.yml index d83fdcc353..a177bc5fe1 100644 --- a/Resources/clientCommandPerms.yml +++ b/Resources/clientCommandPerms.yml @@ -74,6 +74,7 @@ - fullstatereset - dumpentities - showaccessreaders + - quickinspect - Flags: MAPPING Commands: diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index 870c8e1435..aa7b2918e1 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -281,6 +281,14 @@ binds: type: State key: v mod1: Alt +- function: InspectServerComponent + type: State + key: b + mod1: Alt +- function: InspectClientComponent + type: State + key: c + mod1: Alt - function: MouseMiddle type: State key: MouseMiddle