diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 5d3673638..f8e739c1a 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -39,7 +39,7 @@ END TEMPLATE--> ### New features -*None yet* +* Added the `pvs_override_info` command for debugging PVS overrides. ### Bugfixes diff --git a/Resources/Locale/en-US/commands.ftl b/Resources/Locale/en-US/commands.ftl index 6c8d435bf..c997a6550 100644 --- a/Resources/Locale/en-US/commands.ftl +++ b/Resources/Locale/en-US/commands.ftl @@ -566,3 +566,9 @@ cmd-reloadtiletextures-help = Usage: reloadtiletextures cmd-audio_length-desc = Shows the length of an audio file cmd-audio_length-help = Usage: audio_length { cmd-audio_length-arg-file-name } cmd-audio_length-arg-file-name = + +## PVS +cmd-pvs-override-info-desc = Prints information about any PVS overrides associated with an entity. +cmd-pvs-override-info-empty = Entity {$nuid} has no PVS overrides. +cmd-pvs-override-info-global = Entity {$nuid} has a global override. +cmd-pvs-override-info-clients = Entity {$nuid} has a session override for {$clients}. diff --git a/Robust.Server/GameStates/PvsOverrideSystem.cs b/Robust.Server/GameStates/PvsOverrideSystem.cs index b916db783..5f3a46823 100644 --- a/Robust.Server/GameStates/PvsOverrideSystem.cs +++ b/Robust.Server/GameStates/PvsOverrideSystem.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Linq; using Robust.Server.Player; +using Robust.Shared.Console; using Robust.Shared.Enums; using Robust.Shared.GameObjects; using Robust.Shared.IoC; @@ -12,6 +14,7 @@ namespace Robust.Server.GameStates; public sealed class PvsOverrideSystem : EntitySystem { [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IConsoleHost _console = default!; private readonly HashSet _hasOverride = new(); @@ -28,8 +31,64 @@ public sealed class PvsOverrideSystem : EntitySystem SubscribeLocalEvent(OnMapChanged); SubscribeLocalEvent(OnGridCreated); SubscribeLocalEvent(OnGridRemoved); + + // TODO console commands for adding/removing overrides? + _console.RegisterCommand( + "pvs_override_info", + Loc.GetString("cmd-pvs-override-info-desc"), + "pvs_override_info", + GetPvsInfo, + GetCompletion); } + #region Console Commands + + /// + /// Debug command for displaying PVS override information. + /// + private void GetPvsInfo(IConsoleShell shell, string argstr, string[] args) + { + if (args.Length != 1) + { + shell.WriteError(Loc.GetString("cmd-invalid-arg-number-error")); + return; + } + + if (!NetEntity.TryParse(args[0], out var nuid) || !TryGetEntity(nuid, out var uid)) + { + shell.WriteError(Loc.GetString("cmd-parse-failure-uid")); + return; + } + + if (!_hasOverride.Contains(uid.Value)) + { + shell.WriteLine(Loc.GetString("cmd-pvs-override-info-empty", ("nuid", args[0]))); + return; + } + + if (GlobalOverride.Contains(uid.Value) || ForceSend.Contains(uid.Value)) + shell.WriteLine(Loc.GetString("cmd-pvs-override-info-global", ("nuid", args[0]))); + + HashSet sessions = new(); + sessions.UnionWith(SessionOverrides.Where(x => x.Value.Contains(uid.Value)).Select(x => x.Key)); + sessions.UnionWith(SessionForceSend.Where(x => x.Value.Contains(uid.Value)).Select(x => x.Key)); + if (sessions.Count == 0) + return; + + var clients = string.Join(", ", sessions.Select(x => x.ToString())); + shell.WriteLine(Loc.GetString("cmd-pvs-override-info-clients", ("nuid", args[0]), ("clients", clients))); + } + + private CompletionResult GetCompletion(IConsoleShell shell, string[] args) + { + if (args.Length != 1) + return CompletionResult.Empty; + + return CompletionResult.FromHintOptions(CompletionHelper.NetEntities(args[0], EntityManager), "NetEntity"); + } + + #endregion + private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs ev) { if (ev.NewStatus != SessionStatus.Disconnected)