diff --git a/.github/workflows/build-docfx.yml b/.github/workflows/build-docfx.yml index 1f010b7291..3ef0497496 100644 --- a/.github/workflows/build-docfx.yml +++ b/.github/workflows/build-docfx.yml @@ -27,7 +27,7 @@ jobs: run: dotnet restore - name: Build Project - run: dotnet build --no-restore + run: dotnet build --no-restore /p:WarningsAsErrors=nullable - name: Build DocFX uses: nikeee/docfx-action@v1.0.0 diff --git a/.github/workflows/build-map-renderer.yml b/.github/workflows/build-map-renderer.yml index f93f4b25ae..3d01618348 100644 --- a/.github/workflows/build-map-renderer.yml +++ b/.github/workflows/build-map-renderer.yml @@ -42,7 +42,7 @@ jobs: run: dotnet restore - name: Build Project - run: dotnet build Content.MapRenderer --configuration Release --no-restore /m + run: dotnet build Content.MapRenderer --configuration Release --no-restore /p:WarningsAsErrors=nullable /m - name: Run Map Renderer run: dotnet run --project Content.MapRenderer Dev diff --git a/.github/workflows/build-test-debug.yml b/.github/workflows/build-test-debug.yml index 4e391b2aef..369239aecf 100644 --- a/.github/workflows/build-test-debug.yml +++ b/.github/workflows/build-test-debug.yml @@ -42,7 +42,7 @@ jobs: run: dotnet restore - name: Build Project - run: dotnet build --configuration DebugOpt --no-restore /m + run: dotnet build --configuration DebugOpt --no-restore /p:WarningsAsErrors=nullable /m - name: Run Content.Tests run: dotnet test --no-build --configuration DebugOpt Content.Tests/Content.Tests.csproj -- NUnit.ConsoleOut=0 diff --git a/.github/workflows/labeler-needsreview.yml b/.github/workflows/labeler-needsreview.yml index d3373ce91d..819b34b7bb 100644 --- a/.github/workflows/labeler-needsreview.yml +++ b/.github/workflows/labeler-needsreview.yml @@ -2,7 +2,7 @@ on: pull_request_target: - types: [review_requested, opened] + types: [review_requested] jobs: add_label: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3ce5901841..0294395632 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,10 +14,6 @@ jobs: runs-on: ubuntu-latest steps: - - name: Fail if we are attempting to run on the master branch - if: ${{GITHUB.REF_NAME == 'master' && github.repository == 'space-wizards/space-station-14'}} - run: exit 1 - - name: Install dependencies run: sudo apt-get install -y python3-paramiko python3-lxml diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index b2aeb6197a..8554c97ee8 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -27,7 +27,7 @@ If you believe someone is violating the code of conduct, we ask that you report Original text courtesy of the [Speak Up! project](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html). -## On Community Moderation +## On Comunity Moderation Deviating from the Code of Conduct on the Github repository may result in moderative actions taken by project Maintainers. This can involve your content being edited or deleted, and may result in a temporary or permanent block from the repository. diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 83f3a35e72..1466614b25 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -211,7 +211,7 @@ namespace Content.Client.Actions else { var request = new RequestPerformActionEvent(GetNetEntity(action)); - RaisePredictiveEvent(request); + EntityManager.RaisePredictiveEvent(request); } } diff --git a/Content.Client/Administration/AdminNameOverlay.cs b/Content.Client/Administration/AdminNameOverlay.cs index abeed65732..0d424cbff0 100644 --- a/Content.Client/Administration/AdminNameOverlay.cs +++ b/Content.Client/Administration/AdminNameOverlay.cs @@ -1,4 +1,3 @@ -using System.Collections.Frozen; using System.Linq; using System.Numerics; using Content.Client.Administration.Systems; @@ -25,7 +24,6 @@ internal sealed class AdminNameOverlay : Overlay private readonly EntityLookupSystem _entityLookup; private readonly IUserInterfaceManager _userInterfaceManager; private readonly SharedRoleSystem _roles; - private readonly IPrototypeManager _prototypeManager; private readonly Font _font; private readonly Font _fontBold; private AdminOverlayAntagFormat _overlayFormat; @@ -38,9 +36,8 @@ internal sealed class AdminNameOverlay : Overlay private float _overlayMergeDistance; //TODO make this adjustable via GUI? - private static readonly FrozenSet> Filter = - new ProtoId[] {"SoloAntagonist", "TeamAntagonist", "SiliconAntagonist", "FreeAgent"} - .ToFrozenSet(); + private readonly ProtoId[] _filter = + ["SoloAntagonist", "TeamAntagonist", "SiliconAntagonist", "FreeAgent"]; private readonly string _antagLabelClassic = Loc.GetString("admin-overlay-antag-classic"); @@ -52,8 +49,7 @@ internal sealed class AdminNameOverlay : Overlay EntityLookupSystem entityLookup, IUserInterfaceManager userInterfaceManager, IConfigurationManager config, - SharedRoleSystem roles, - IPrototypeManager prototypeManager) + SharedRoleSystem roles) { _system = system; _entityManager = entityManager; @@ -61,7 +57,6 @@ internal sealed class AdminNameOverlay : Overlay _entityLookup = entityLookup; _userInterfaceManager = userInterfaceManager; _roles = roles; - _prototypeManager = prototypeManager; ZIndex = 200; // Setting these to a specific ttf would break the antag symbols _font = resourceCache.NotoStack(); @@ -130,14 +125,6 @@ internal sealed class AdminNameOverlay : Overlay foreach (var info in sortable.OrderBy(s => s.Item4.Y).ToList()) { var playerInfo = info.Item1; - var rolePrototype = playerInfo.RoleProto == null - ? null - : _prototypeManager.Index(playerInfo.RoleProto.Value); - - var roleName = Loc.GetString(rolePrototype?.Name ?? RoleTypePrototype.FallbackName); - var roleColor = rolePrototype?.Color ?? RoleTypePrototype.FallbackColor; - var roleSymbol = rolePrototype?.Symbol ?? RoleTypePrototype.FallbackSymbol; - var aabb = info.Item2; var entity = info.Item3; var screenCoordinatesCenter = info.Item4; @@ -222,7 +209,7 @@ internal sealed class AdminNameOverlay : Overlay switch (_overlaySymbolStyle) { case AdminOverlayAntagSymbolStyle.Specific: - symbol = roleSymbol; + symbol = playerInfo.RoleProto.Symbol; break; case AdminOverlayAntagSymbolStyle.Basic: symbol = Loc.GetString("player-tab-antag-prefix"); @@ -238,17 +225,17 @@ internal sealed class AdminNameOverlay : Overlay switch (_overlayFormat) { case AdminOverlayAntagFormat.Roletype: - color = roleColor; - symbol = IsFiltered(playerInfo.RoleProto) ? symbol : string.Empty; - text = IsFiltered(playerInfo.RoleProto) - ? roleName.ToUpper() + color = playerInfo.RoleProto.Color; + symbol = _filter.Contains(playerInfo.RoleProto) ? symbol : string.Empty; + text = _filter.Contains(playerInfo.RoleProto) + ? Loc.GetString(playerInfo.RoleProto.Name).ToUpper() : string.Empty; break; case AdminOverlayAntagFormat.Subtype: - color = roleColor; - symbol = IsFiltered(playerInfo.RoleProto) ? symbol : string.Empty; - text = IsFiltered(playerInfo.RoleProto) - ? _roles.GetRoleSubtypeLabel(roleName, playerInfo.Subtype).ToUpper() + color = playerInfo.RoleProto.Color; + symbol = _filter.Contains(playerInfo.RoleProto) ? symbol : string.Empty; + text = _filter.Contains(playerInfo.RoleProto) + ? _roles.GetRoleSubtypeLabel(playerInfo.RoleProto.Name, playerInfo.Subtype).ToUpper() : string.Empty; break; default: @@ -271,12 +258,4 @@ internal sealed class AdminNameOverlay : Overlay drawnOverlays.Add((screenCoordinatesCenter, currentOffset)); } } - - private static bool IsFiltered(ProtoId? roleProtoId) - { - if (roleProtoId == null) - return false; - - return Filter.Contains(roleProtoId.Value); - } } diff --git a/Content.Client/Administration/Systems/AdminSystem.Overlay.cs b/Content.Client/Administration/Systems/AdminSystem.Overlay.cs index e000bdc0ba..a630df4521 100644 --- a/Content.Client/Administration/Systems/AdminSystem.Overlay.cs +++ b/Content.Client/Administration/Systems/AdminSystem.Overlay.cs @@ -4,7 +4,6 @@ using Robust.Client.Graphics; using Robust.Client.ResourceManagement; using Robust.Client.UserInterface; using Robust.Shared.Configuration; -using Robust.Shared.Prototypes; namespace Content.Client.Administration.Systems { @@ -18,7 +17,6 @@ namespace Content.Client.Administration.Systems [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; [Dependency] private readonly SharedRoleSystem _roles = default!; - [Dependency] private readonly IPrototypeManager _proto = default!; private AdminNameOverlay _adminNameOverlay = default!; @@ -35,8 +33,7 @@ namespace Content.Client.Administration.Systems _entityLookup, _userInterfaceManager, _configurationManager, - _roles, - _proto); + _roles); _adminManager.AdminStatusUpdated += OnAdminStatusUpdated; } diff --git a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml index ede0ad3ee5..333184f1c0 100644 --- a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml +++ b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml @@ -1,7 +1,7 @@ + Title="{Loc ban-panel-title}" MinSize="350 500"> diff --git a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs index 46090a6f3d..3c7322d473 100644 --- a/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs +++ b/Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs @@ -1,14 +1,12 @@ using System.Linq; using System.Net; using System.Net.Sockets; -using System.Numerics; using Content.Client.Administration.UI.CustomControls; using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.Roles; using Robust.Client.AutoGenerated; -using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; @@ -33,21 +31,14 @@ public sealed partial class BanPanel : DefaultWindow private uint Multiplier { get; set; } private bool HasBanFlag { get; set; } private TimeSpan? ButtonResetOn { get; set; } - // This is less efficient than just holding a reference to the root control and enumerating children, but you // have to know how the controls are nested, which makes the code more complicated. - // Role group name -> the role buttons themselves. - private readonly Dictionary> _roleCheckboxes = new(); + private readonly List _roleCheckboxes = new(); private readonly ISawmill _banpanelSawmill; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly IEntityManager _entMan = default!; - [Dependency] private readonly IPrototypeManager _protoMan = default!; - - private const string ExpandedArrow = "▼"; - private const string ContractedArrow = "▶"; private enum TabNumbers { @@ -153,90 +144,47 @@ public sealed partial class BanPanel : DefaultWindow ReasonTextEdit.Placeholder = new Rope.Leaf(Loc.GetString("ban-panel-reason")); - var departmentJobs = _protoMan.EnumeratePrototypes() - .OrderBy(x => x.Weight); - foreach (var proto in departmentJobs) + var prototypeManager = IoCManager.Resolve(); + foreach (var proto in prototypeManager.EnumeratePrototypes()) { - var roles = proto.Roles.Select(x => _protoMan.Index(x)) - .OrderBy(x => x.ID); - CreateRoleGroup(proto.ID, proto.Color, roles); + CreateRoleGroup(proto.ID, proto.Roles.Select(p => p.Id), proto.Color); } - var antagRoles = _protoMan.EnumeratePrototypes() - .OrderBy(x => x.ID); - CreateRoleGroup("Antagonist", Color.Red, antagRoles); + CreateRoleGroup("Antagonist", prototypeManager.EnumeratePrototypes().Select(p => p.ID), Color.Red); } - /// - /// Creates a "Role group" which stores information and logic for one "group" of roll bans. - /// For example, all antags are one group, logi is a group, medical is a group, etc... - /// - private void CreateRoleGroup(string groupName, Color color, IEnumerable roles) where T : class, IPrototype + private void CreateRoleGroup(string roleName, IEnumerable roleList, Color color) { var outerContainer = new BoxContainer { - Name = $"{groupName}GroupOuterBox", + Name = $"{roleName}GroupOuterBox", HorizontalExpand = true, VerticalExpand = true, Orientation = BoxContainer.LayoutOrientation.Vertical, - Margin = new Thickness(4), + Margin = new Thickness(4) }; - - // Stores stuff like ban all and expand buttons. - var roleGroupHeader = new BoxContainer + var departmentCheckbox = new CheckBox { - Orientation = BoxContainer.LayoutOrientation.Horizontal, + Name = $"{roleName}GroupCheckbox", + Text = roleName, + Modulate = color, + HorizontalAlignment = HAlignment.Left }; - - // Stores the role checkboxes themselves. - var innerContainer = new GridContainer + outerContainer.AddChild(departmentCheckbox); + var innerContainer = new BoxContainer { - Name = $"{groupName}GroupInnerBox", + Name = $"{roleName}GroupInnerBox", HorizontalExpand = true, - Columns = 2, - Visible = false, - Margin = new Thickness(15, 5, 0, 5), + Orientation = BoxContainer.LayoutOrientation.Horizontal }; - - var roleGroupCheckbox = CreateRoleGroupHeader(groupName, roleGroupHeader, color, innerContainer); - - outerContainer.AddChild(roleGroupHeader); - - // Add the roles themselves - foreach (var role in roles) + departmentCheckbox.OnToggled += args => { - AddRoleCheckbox(groupName, role.ID, innerContainer, roleGroupCheckbox); - } - - outerContainer.AddChild(innerContainer); - - RolesContainer.AddChild(new PanelContainer - { - PanelOverride = new StyleBoxFlat + foreach (var child in innerContainer.Children) { - BackgroundColor = color - } - }); - RolesContainer.AddChild(outerContainer); - RolesContainer.AddChild(new HSeparator()); - } - - private Button CreateRoleGroupHeader(string groupName, BoxContainer header, Color color, GridContainer innerContainer) - { - var roleGroupCheckbox = new Button - { - Name = $"{groupName}GroupCheckbox", - Text = "Ban all", - Margin = new Thickness(0, 0, 5, 0), - ToggleMode = true, - }; - - // When this is toggled, toggle all buttons in this group so they match. - roleGroupCheckbox.OnToggled += args => - { - foreach (var role in _roleCheckboxes[groupName]) - { - role.Pressed = args.Pressed; + if (child is CheckBox c) + { + c.Pressed = args.Pressed; + } } if (args.Pressed) @@ -251,12 +199,15 @@ public sealed partial class BanPanel : DefaultWindow } else { - foreach (var roleButtons in _roleCheckboxes.Values) + foreach (var childContainer in RolesContainer.Children) { - foreach (var button in roleButtons) + if (childContainer is Container) { - if (button.Pressed) - return; + foreach (var child in childContainer.Children) + { + if (child is CheckBox { Pressed: true }) + return; + } } } @@ -269,72 +220,38 @@ public sealed partial class BanPanel : DefaultWindow SeverityOption.SelectId((int) newSeverity); } }; - - var hideButton = new Button + outerContainer.AddChild(innerContainer); + foreach (var role in roleList) { - Text = Loc.GetString("role-bans-expand-roles") + " " + ContractedArrow, - ToggleMode = true, - }; - hideButton.OnPressed += args => + AddRoleCheckbox(role, innerContainer, departmentCheckbox); + } + RolesContainer.AddChild(new PanelContainer { - innerContainer.Visible = args.Button.Pressed; - ((Button)args.Button).Text = args.Button.Pressed - ? Loc.GetString("role-bans-contract-roles") + " " + ExpandedArrow - : Loc.GetString("role-bans-expand-roles") + " " + ContractedArrow; - }; - header.AddChild(new Label - { - Text = groupName, - Modulate = color, - Margin = new Thickness(0, 0, 5, 0), + PanelOverride = new StyleBoxFlat + { + BackgroundColor = color + } }); - header.AddChild(roleGroupCheckbox); - header.AddChild(hideButton); - return roleGroupCheckbox; + RolesContainer.AddChild(outerContainer); + RolesContainer.AddChild(new HSeparator()); } - /// - /// Adds a checkbutton specifically for one "role" in a "group" - /// E.g. it would add the Chief Medical Officer "role" into the "Medical" group. - /// - private void AddRoleCheckbox(string group, string role, GridContainer roleGroupInnerContainer, Button roleGroupCheckbox) + private void AddRoleCheckbox(string role, Control container, CheckBox header) { - var roleCheckboxContainer = new BoxContainer(); - var roleCheckButton = new Button + var roleCheckbox = new CheckBox { Name = $"{role}RoleCheckbox", - Text = role, - ToggleMode = true, + Text = role }; - roleCheckButton.OnToggled += args => + roleCheckbox.OnToggled += args => { - // Checks the role group checkbox if all the children are pressed - if (args.Pressed && _roleCheckboxes[group].All(e => e.Pressed)) - roleGroupCheckbox.Pressed = args.Pressed; + if (args is { Pressed: true, Button.Parent: { } } && args.Button.Parent.Children.Where(e => e is CheckBox).All(e => ((CheckBox) e).Pressed)) + header.Pressed = args.Pressed; else - roleGroupCheckbox.Pressed = false; + header.Pressed = false; }; - - // This is adding the icon before the role name - // Yeah, this is sus, but having to split the functions up and stuff is worse imo. - if (_protoMan.TryIndex(role, out var jobPrototype) && _protoMan.TryIndex(jobPrototype.Icon, out var iconProto)) - { - var jobIconTexture = new TextureRect - { - Texture = _entMan.System().Frame0(iconProto.Icon), - TextureScale = new Vector2(2.5f, 2.5f), - Stretch = TextureRect.StretchMode.KeepCentered, - Margin = new Thickness(5, 0, 0, 0), - }; - roleCheckboxContainer.AddChild(jobIconTexture); - } - - roleCheckboxContainer.AddChild(roleCheckButton); - - roleGroupInnerContainer.AddChild(roleCheckboxContainer); - - _roleCheckboxes.TryAdd(group, []); - _roleCheckboxes[group].Add(roleCheckButton); + container.AddChild(roleCheckbox); + _roleCheckboxes.Add(roleCheckbox); } public void UpdateBanFlag(bool newFlag) @@ -552,13 +469,7 @@ public sealed partial class BanPanel : DefaultWindow if (_roleCheckboxes.Count == 0) throw new DebugAssertException("RoleCheckboxes was empty"); - foreach (var button in _roleCheckboxes.Values.SelectMany(departmentButtons => departmentButtons)) - { - if (button is { Pressed: true, Text: not null }) - { - rolesList.Add(button.Text); - } - } + rolesList.AddRange(_roleCheckboxes.Where(c => c is { Pressed: true, Text: { } }).Select(c => c.Text!)); if (rolesList.Count == 0) { diff --git a/Content.Client/Administration/UI/Logs/AdminLogsControl.xaml b/Content.Client/Administration/UI/Logs/AdminLogsControl.xaml index cd93ffeb0a..fc4d3ee3ac 100644 --- a/Content.Client/Administration/UI/Logs/AdminLogsControl.xaml +++ b/Content.Client/Administration/UI/Logs/AdminLogsControl.xaml @@ -49,7 +49,6 @@