diff --git a/.editorconfig b/.editorconfig index 872a068c7c6..58d0d332bbe 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ indent_style = space tab_width = 4 # New line preferences -#end_of_line = crlf +end_of_line = crlf:suggestion insert_final_newline = true trim_trailing_whitespace = true @@ -104,6 +104,7 @@ csharp_preferred_modifier_order = public, private, protected, internal, new, abs # 'using' directive preferences csharp_using_directive_placement = outside_namespace:silent +csharp_style_namespace_declarations = file_scoped:suggestion #### C# Formatting Rules #### diff --git a/.vscode/settings.json b/.vscode/settings.json index 0e0d3ae890c..dc6e26cbeaa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,10 @@ { "omnisharp.analyzeOpenDocumentsOnly": true, - "dotnet.defaultSolution": "SpaceStation14.sln" + "dotnet.defaultSolution": "SpaceStation14.sln", + "json.schemas": [ + { + "fileMatch": [ "**/meta.json" ], + "url": "https://raw.githubusercontent.com/Simple-Station/Einstein-Engines/master/.github/rsi-schema.json" + } + ] } diff --git a/Content.Client/Access/AccessOverlay.cs b/Content.Client/Access/AccessOverlay.cs index 2be3d07e90d..59c9441036d 100644 --- a/Content.Client/Access/AccessOverlay.cs +++ b/Content.Client/Access/AccessOverlay.cs @@ -9,20 +9,20 @@ namespace Content.Client.Access; public sealed class AccessOverlay : Overlay { + private const string TextFontPath = "/Fonts/NotoSans/NotoSans-Regular.ttf"; + private const int TextFontSize = 12; + private readonly IEntityManager _entityManager; - private readonly EntityLookupSystem _lookup; - private readonly SharedTransformSystem _xform; + private readonly SharedTransformSystem _transformSystem; private readonly Font _font; public override OverlaySpace Space => OverlaySpace.ScreenSpace; - public AccessOverlay(IEntityManager entManager, IResourceCache cache, EntityLookupSystem lookup, SharedTransformSystem xform) + public AccessOverlay(IEntityManager entityManager, IResourceCache resourceCache, SharedTransformSystem transformSystem) { - _entityManager = entManager; - _lookup = lookup; - _xform = xform; - - _font = cache.GetFont("/Fonts/NotoSans/NotoSans-Regular.ttf", 12); + _entityManager = entityManager; + _transformSystem = transformSystem; + _font = resourceCache.GetFont(TextFontPath, TextFontSize); } protected override void Draw(in OverlayDrawArgs args) @@ -30,52 +30,65 @@ protected override void Draw(in OverlayDrawArgs args) if (args.ViewportControl == null) return; - var readerQuery = _entityManager.GetEntityQuery(); - var xformQuery = _entityManager.GetEntityQuery(); - - foreach (var ent in _lookup.GetEntitiesIntersecting(args.MapId, args.WorldAABB, - LookupFlags.Static | LookupFlags.Approximate)) + var textBuffer = new StringBuilder(); + var query = _entityManager.EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var accessReader, out var transform)) { - if (!readerQuery.TryGetComponent(ent, out var reader) || - !xformQuery.TryGetComponent(ent, out var xform)) + textBuffer.Clear(); + + var entityName = _entityManager.ToPrettyString(uid); + textBuffer.AppendLine(entityName.Prototype); + textBuffer.Append("UID: "); + textBuffer.Append(entityName.Uid.Id); + textBuffer.Append(", NUID: "); + textBuffer.Append(entityName.Nuid.Id); + textBuffer.AppendLine(); + + if (!accessReader.Enabled) { + textBuffer.AppendLine("-Disabled"); continue; } - var text = new StringBuilder(); - var index = 0; - var a = $"{_entityManager.ToPrettyString(ent)}"; - text.Append(a); - - foreach (var list in reader.AccessLists) + if (accessReader.AccessLists.Count > 0) { - a = $"Tag {index}"; - text.AppendLine(a); - - foreach (var entry in list) + var groupNumber = 0; + foreach (var accessList in accessReader.AccessLists) { - a = $"- {entry}"; - text.AppendLine(a); + groupNumber++; + foreach (var entry in accessList) + { + textBuffer.Append("+Set "); + textBuffer.Append(groupNumber); + textBuffer.Append(": "); + textBuffer.Append(entry.Id); + textBuffer.AppendLine(); + } } - - index++; } - - string textStr; - - if (text.Length >= 2) + else { - textStr = text.ToString(); - textStr = textStr[..^2]; + textBuffer.AppendLine("+Unrestricted"); } - else + + foreach (var key in accessReader.AccessKeys) { - textStr = ""; + textBuffer.Append("+Key "); + textBuffer.Append(key.OriginStation); + textBuffer.Append(": "); + textBuffer.Append(key.Id); + textBuffer.AppendLine(); } - var screenPos = args.ViewportControl.WorldToScreen(_xform.GetWorldPosition(xform)); + foreach (var tag in accessReader.DenyTags) + { + textBuffer.Append("-Tag "); + textBuffer.AppendLine(tag.Id); + } - args.ScreenHandle.DrawString(_font, screenPos, textStr, Color.Gold); + var accessInfoText = textBuffer.ToString(); + var screenPos = args.ViewportControl.WorldToScreen(_transformSystem.GetWorldPosition(transform)); + args.ScreenHandle.DrawString(_font, screenPos, accessInfoText, Color.Gold); } } } diff --git a/Content.Client/Access/Commands/ShowAccessReadersCommand.cs b/Content.Client/Access/Commands/ShowAccessReadersCommand.cs index 7c804dd9698..cb6cb6cf6bb 100644 --- a/Content.Client/Access/Commands/ShowAccessReadersCommand.cs +++ b/Content.Client/Access/Commands/ShowAccessReadersCommand.cs @@ -7,8 +7,16 @@ namespace Content.Client.Access.Commands; public sealed class ShowAccessReadersCommand : IConsoleCommand { public string Command => "showaccessreaders"; - public string Description => "Shows all access readers in the viewport"; - public string Help => $"{Command}"; + + public string Description => "Toggles showing access reader permissions on the map"; + public string Help => """ + Overlay Info: + -Disabled | The access reader is disabled + +Unrestricted | The access reader has no restrictions + +Set [Index]: [Tag Name]| A tag in an access set (accessor needs all tags in the set to be allowed by the set) + +Key [StationUid]: [StationRecordKeyId] | A StationRecordKey that is allowed + -Tag [Tag Name] | A tag that is not allowed (takes priority over other allows) + """; public void Execute(IConsoleShell shell, string argStr, string[] args) { var collection = IoCManager.Instance; @@ -26,10 +34,9 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) var entManager = collection.Resolve(); var cache = collection.Resolve(); - var lookup = entManager.System(); var xform = entManager.System(); - overlay.AddOverlay(new AccessOverlay(entManager, cache, lookup, xform)); + overlay.AddOverlay(new AccessOverlay(entManager, cache, xform)); shell.WriteLine($"Set access reader debug overlay to true"); } } diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml b/Content.Client/Access/UI/AccessLevelControl.xaml new file mode 100644 index 00000000000..56968d89839 --- /dev/null +++ b/Content.Client/Access/UI/AccessLevelControl.xaml @@ -0,0 +1,4 @@ + + diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml.cs b/Content.Client/Access/UI/AccessLevelControl.xaml.cs new file mode 100644 index 00000000000..34db80b7af9 --- /dev/null +++ b/Content.Client/Access/UI/AccessLevelControl.xaml.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Prototypes; +using Content.Shared.Access; +using Content.Shared.Access.Systems; + +namespace Content.Client.Access.UI; + +[GenerateTypedNameReferences] +public sealed partial class AccessLevelControl : GridContainer +{ + public readonly Dictionary, Button> ButtonsList = new(); + + public AccessLevelControl() + { + RobustXamlLoader.Load(this); + } + + public void Populate(List> accessLevels, IPrototypeManager prototypeManager) + { + foreach (var access in accessLevels) + { + if (!prototypeManager.TryIndex(access, out var accessLevel)) + { + Logger.Error($"Unable to find accesslevel for {access}"); + continue; + } + + var newButton = new Button + { + Text = accessLevel.GetAccessLevelName(), + ToggleMode = true, + }; + AddChild(newButton); + ButtonsList.Add(accessLevel.ID, newButton); + } + } + + public void UpdateState( + List> pressedList, + List>? enabledList = null) + { + foreach (var (accessName, button) in ButtonsList) + { + button.Pressed = pressedList.Contains(accessName); + button.Disabled = !(enabledList?.Contains(accessName) ?? true); + } + } +} diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index 0c23542f798..c1b63dc4d05 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -64,7 +64,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } - public void SubmitData(List newAccessList) + public void SubmitData(List> newAccessList) { SendMessage(new WriteToTargetAccessReaderIdMessage(newAccessList)); } diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs index 2fd00571215..6025c3b551f 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs @@ -16,7 +16,6 @@ public sealed partial class AccessOverriderWindow : DefaultWindow [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private readonly ISawmill _logMill = default!; private readonly AccessOverriderBoundUserInterface _owner; private readonly Dictionary _accessButtons = new(); @@ -25,7 +24,7 @@ public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototype { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); + var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); _owner = owner; @@ -33,13 +32,13 @@ public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototype { if (!prototypeManager.TryIndex(access, out var accessLevel)) { - _logMill.Error($"Unable to find accesslevel for {access}"); + logMill.Error($"Unable to find accesslevel for {access}"); continue; } var newButton = new Button { - Text = GetAccessLevelName(accessLevel), + Text = accessLevel.GetAccessLevelName(), ToggleMode = true, }; @@ -49,14 +48,6 @@ public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototype } } - private static string GetAccessLevelName(AccessLevelPrototype prototype) - { - if (prototype.Name is { } name) - return Loc.GetString(name); - - return prototype.ID; - } - public void UpdateState(AccessOverriderBoundUserInterfaceState state) { PrivilegedIdLabel.Text = state.PrivilegedIdName; @@ -105,7 +96,7 @@ private void SubmitData() _owner.SubmitData( // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair - _accessButtons.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); + _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); } } } diff --git a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs index 898792aa030..5b7011c195a 100644 --- a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs +++ b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Access; using Content.Shared.Access.Components; +using Content.Shared.Access; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; using Content.Shared.CrewManifest; @@ -28,7 +29,6 @@ protected override void Open() if (EntMan.TryGetComponent(Owner, out var idCard)) { accessLevels = idCard.AccessLevels; - accessLevels.Sort(); } else { @@ -65,7 +65,7 @@ protected override void UpdateState(BoundUserInterfaceState state) _window?.UpdateState(castState); } - public void SubmitData(string newFullName, string newJobTitle, List newAccessList, string newJobPrototype) + public void SubmitData(string newFullName, string newJobTitle, List> newAccessList, string newJobPrototype) { if (newFullName.Length > MaxFullNameLength) newFullName = newFullName[..MaxFullNameLength]; diff --git a/Content.Client/Access/UI/IdCardConsoleWindow.xaml b/Content.Client/Access/UI/IdCardConsoleWindow.xaml index c29adc8ebd3..a2f5f3382bb 100644 --- a/Content.Client/Access/UI/IdCardConsoleWindow.xaml +++ b/Content.Client/Access/UI/IdCardConsoleWindow.xaml @@ -30,10 +30,6 @@