Skip to content

Commit 43c032a

Browse files
Merge pull request #34 from EmoGarbage404/upstream/6-25
Upstream 6-25-25
2 parents 0207f51 + 693dabf commit 43c032a

File tree

1,048 files changed

+163309
-18429
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,048 files changed

+163309
-18429
lines changed

.github/workflows/build-docfx.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
run: dotnet restore
2828

2929
- name: Build Project
30-
run: dotnet build --no-restore /p:WarningsAsErrors=nullable
30+
run: dotnet build --no-restore
3131

3232
- name: Build DocFX
3333
uses: nikeee/docfx-action@v1.0.0

.github/workflows/build-map-renderer.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
run: dotnet restore
4343

4444
- name: Build Project
45-
run: dotnet build Content.MapRenderer --configuration Release --no-restore /p:WarningsAsErrors=nullable /m
45+
run: dotnet build Content.MapRenderer --configuration Release --no-restore /m
4646

4747
- name: Run Map Renderer
4848
run: dotnet run --project Content.MapRenderer Dev

.github/workflows/build-test-debug.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
run: dotnet restore
4343

4444
- name: Build Project
45-
run: dotnet build --configuration DebugOpt --no-restore /p:WarningsAsErrors=nullable /m
45+
run: dotnet build --configuration DebugOpt --no-restore /m
4646

4747
- name: Run Content.Tests
4848
run: dotnet test --no-build --configuration DebugOpt Content.Tests/Content.Tests.csproj -- NUnit.ConsoleOut=0

.github/workflows/publish.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ jobs:
1414
runs-on: ubuntu-latest
1515

1616
steps:
17+
- name: Fail if we are attempting to run on the master branch
18+
if: ${{GITHUB.REF_NAME == 'master' && github.repository == 'space-wizards/space-station-14'}}
19+
run: exit 1
20+
1721
- name: Install dependencies
1822
run: sudo apt-get install -y python3-paramiko python3-lxml
1923

CODE_OF_CONDUCT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ If you believe someone is violating the code of conduct, we ask that you report
2727

2828
Original text courtesy of the [Speak Up! project](http://web.archive.org/web/20141109123859/http://speakup.io/coc.html).
2929

30-
## On Comunity Moderation
30+
## On Community Moderation
3131

3232
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.
3333

Content.Client/Administration/UI/BanPanel/BanPanel.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<DefaultWindow
22
xmlns="https://spacestation14.io"
33
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
4-
Title="{Loc ban-panel-title}" MinSize="350 500">
4+
Title="{Loc ban-panel-title}" MinSize="410 500">
55
<BoxContainer Orientation="Vertical">
66
<TabContainer Name="Tabs" VerticalExpand="True">
77
<!-- Basic info -->

Content.Client/Administration/UI/BanPanel/BanPanel.xaml.cs

Lines changed: 140 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using System.Linq;
22
using System.Net;
33
using System.Net.Sockets;
4+
using System.Numerics;
45
using Content.Client.Administration.UI.CustomControls;
56
using Content.Shared.Administration;
67
using Content.Shared.CCVar;
78
using Content.Shared.Database;
89
using Content.Shared.Roles;
910
using Robust.Client.AutoGenerated;
11+
using Robust.Client.GameObjects;
1012
using Robust.Client.Graphics;
1113
using Robust.Client.UserInterface;
1214
using Robust.Client.UserInterface.Controls;
@@ -31,14 +33,21 @@ public sealed partial class BanPanel : DefaultWindow
3133
private uint Multiplier { get; set; }
3234
private bool HasBanFlag { get; set; }
3335
private TimeSpan? ButtonResetOn { get; set; }
36+
3437
// This is less efficient than just holding a reference to the root control and enumerating children, but you
3538
// have to know how the controls are nested, which makes the code more complicated.
36-
private readonly List<CheckBox> _roleCheckboxes = new();
39+
// Role group name -> the role buttons themselves.
40+
private readonly Dictionary<string, List<Button>> _roleCheckboxes = new();
3741
private readonly ISawmill _banpanelSawmill;
3842

3943
[Dependency] private readonly IGameTiming _gameTiming = default!;
4044
[Dependency] private readonly IConfigurationManager _cfg = default!;
4145
[Dependency] private readonly ILogManager _logManager = default!;
46+
[Dependency] private readonly IEntityManager _entMan = default!;
47+
[Dependency] private readonly IPrototypeManager _protoMan = default!;
48+
49+
private const string ExpandedArrow = "▼";
50+
private const string ContractedArrow = "▶";
4251

4352
private enum TabNumbers
4453
{
@@ -144,47 +153,90 @@ public BanPanel()
144153

145154
ReasonTextEdit.Placeholder = new Rope.Leaf(Loc.GetString("ban-panel-reason"));
146155

147-
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
148-
foreach (var proto in prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
156+
var departmentJobs = _protoMan.EnumeratePrototypes<DepartmentPrototype>()
157+
.OrderBy(x => x.Weight);
158+
foreach (var proto in departmentJobs)
149159
{
150-
CreateRoleGroup(proto.ID, proto.Roles.Select(p => p.Id), proto.Color);
160+
var roles = proto.Roles.Select(x => _protoMan.Index(x))
161+
.OrderBy(x => x.ID);
162+
CreateRoleGroup(proto.ID, proto.Color, roles);
151163
}
152164

153-
CreateRoleGroup("Antagonist", prototypeManager.EnumeratePrototypes<AntagPrototype>().Select(p => p.ID), Color.Red);
165+
var antagRoles = _protoMan.EnumeratePrototypes<AntagPrototype>()
166+
.OrderBy(x => x.ID);
167+
CreateRoleGroup("Antagonist", Color.Red, antagRoles);
154168
}
155169

156-
private void CreateRoleGroup(string roleName, IEnumerable<string> roleList, Color color)
170+
/// <summary>
171+
/// Creates a "Role group" which stores information and logic for one "group" of roll bans.
172+
/// For example, all antags are one group, logi is a group, medical is a group, etc...
173+
/// </summary>
174+
private void CreateRoleGroup<T>(string groupName, Color color, IEnumerable<T> roles) where T : class, IPrototype
157175
{
158176
var outerContainer = new BoxContainer
159177
{
160-
Name = $"{roleName}GroupOuterBox",
178+
Name = $"{groupName}GroupOuterBox",
161179
HorizontalExpand = true,
162180
VerticalExpand = true,
163181
Orientation = BoxContainer.LayoutOrientation.Vertical,
164-
Margin = new Thickness(4)
182+
Margin = new Thickness(4),
165183
};
166-
var departmentCheckbox = new CheckBox
184+
185+
// Stores stuff like ban all and expand buttons.
186+
var roleGroupHeader = new BoxContainer
167187
{
168-
Name = $"{roleName}GroupCheckbox",
169-
Text = roleName,
170-
Modulate = color,
171-
HorizontalAlignment = HAlignment.Left
188+
Orientation = BoxContainer.LayoutOrientation.Horizontal,
172189
};
173-
outerContainer.AddChild(departmentCheckbox);
174-
var innerContainer = new BoxContainer
190+
191+
// Stores the role checkboxes themselves.
192+
var innerContainer = new GridContainer
175193
{
176-
Name = $"{roleName}GroupInnerBox",
194+
Name = $"{groupName}GroupInnerBox",
177195
HorizontalExpand = true,
178-
Orientation = BoxContainer.LayoutOrientation.Horizontal
196+
Columns = 2,
197+
Visible = false,
198+
Margin = new Thickness(15, 5, 0, 5),
179199
};
180-
departmentCheckbox.OnToggled += args =>
200+
201+
var roleGroupCheckbox = CreateRoleGroupHeader(groupName, roleGroupHeader, color, innerContainer);
202+
203+
outerContainer.AddChild(roleGroupHeader);
204+
205+
// Add the roles themselves
206+
foreach (var role in roles)
207+
{
208+
AddRoleCheckbox(groupName, role.ID, innerContainer, roleGroupCheckbox);
209+
}
210+
211+
outerContainer.AddChild(innerContainer);
212+
213+
RolesContainer.AddChild(new PanelContainer
181214
{
182-
foreach (var child in innerContainer.Children)
215+
PanelOverride = new StyleBoxFlat
183216
{
184-
if (child is CheckBox c)
185-
{
186-
c.Pressed = args.Pressed;
187-
}
217+
BackgroundColor = color
218+
}
219+
});
220+
RolesContainer.AddChild(outerContainer);
221+
RolesContainer.AddChild(new HSeparator());
222+
}
223+
224+
private Button CreateRoleGroupHeader(string groupName, BoxContainer header, Color color, GridContainer innerContainer)
225+
{
226+
var roleGroupCheckbox = new Button
227+
{
228+
Name = $"{groupName}GroupCheckbox",
229+
Text = "Ban all",
230+
Margin = new Thickness(0, 0, 5, 0),
231+
ToggleMode = true,
232+
};
233+
234+
// When this is toggled, toggle all buttons in this group so they match.
235+
roleGroupCheckbox.OnToggled += args =>
236+
{
237+
foreach (var role in _roleCheckboxes[groupName])
238+
{
239+
role.Pressed = args.Pressed;
188240
}
189241

190242
if (args.Pressed)
@@ -199,15 +251,12 @@ private void CreateRoleGroup(string roleName, IEnumerable<string> roleList, Colo
199251
}
200252
else
201253
{
202-
foreach (var childContainer in RolesContainer.Children)
254+
foreach (var roleButtons in _roleCheckboxes.Values)
203255
{
204-
if (childContainer is Container)
256+
foreach (var button in roleButtons)
205257
{
206-
foreach (var child in childContainer.Children)
207-
{
208-
if (child is CheckBox { Pressed: true })
209-
return;
210-
}
258+
if (button.Pressed)
259+
return;
211260
}
212261
}
213262

@@ -220,38 +269,72 @@ private void CreateRoleGroup(string roleName, IEnumerable<string> roleList, Colo
220269
SeverityOption.SelectId((int) newSeverity);
221270
}
222271
};
223-
outerContainer.AddChild(innerContainer);
224-
foreach (var role in roleList)
272+
273+
var hideButton = new Button
225274
{
226-
AddRoleCheckbox(role, innerContainer, departmentCheckbox);
227-
}
228-
RolesContainer.AddChild(new PanelContainer
275+
Text = Loc.GetString("role-bans-expand-roles") + " " + ContractedArrow,
276+
ToggleMode = true,
277+
};
278+
hideButton.OnPressed += args =>
229279
{
230-
PanelOverride = new StyleBoxFlat
231-
{
232-
BackgroundColor = color
233-
}
280+
innerContainer.Visible = args.Button.Pressed;
281+
((Button)args.Button).Text = args.Button.Pressed
282+
? Loc.GetString("role-bans-contract-roles") + " " + ExpandedArrow
283+
: Loc.GetString("role-bans-expand-roles") + " " + ContractedArrow;
284+
};
285+
header.AddChild(new Label
286+
{
287+
Text = groupName,
288+
Modulate = color,
289+
Margin = new Thickness(0, 0, 5, 0),
234290
});
235-
RolesContainer.AddChild(outerContainer);
236-
RolesContainer.AddChild(new HSeparator());
291+
header.AddChild(roleGroupCheckbox);
292+
header.AddChild(hideButton);
293+
return roleGroupCheckbox;
237294
}
238295

239-
private void AddRoleCheckbox(string role, Control container, CheckBox header)
296+
/// <summary>
297+
/// Adds a checkbutton specifically for one "role" in a "group"
298+
/// E.g. it would add the Chief Medical Officer "role" into the "Medical" group.
299+
/// </summary>
300+
private void AddRoleCheckbox(string group, string role, GridContainer roleGroupInnerContainer, Button roleGroupCheckbox)
240301
{
241-
var roleCheckbox = new CheckBox
302+
var roleCheckboxContainer = new BoxContainer();
303+
var roleCheckButton = new Button
242304
{
243305
Name = $"{role}RoleCheckbox",
244-
Text = role
306+
Text = role,
307+
ToggleMode = true,
245308
};
246-
roleCheckbox.OnToggled += args =>
309+
roleCheckButton.OnToggled += args =>
247310
{
248-
if (args is { Pressed: true, Button.Parent: { } } && args.Button.Parent.Children.Where(e => e is CheckBox).All(e => ((CheckBox) e).Pressed))
249-
header.Pressed = args.Pressed;
311+
// Checks the role group checkbox if all the children are pressed
312+
if (args.Pressed && _roleCheckboxes[group].All(e => e.Pressed))
313+
roleGroupCheckbox.Pressed = args.Pressed;
250314
else
251-
header.Pressed = false;
315+
roleGroupCheckbox.Pressed = false;
252316
};
253-
container.AddChild(roleCheckbox);
254-
_roleCheckboxes.Add(roleCheckbox);
317+
318+
// This is adding the icon before the role name
319+
// Yeah, this is sus, but having to split the functions up and stuff is worse imo.
320+
if (_protoMan.TryIndex<JobPrototype>(role, out var jobPrototype) && _protoMan.TryIndex(jobPrototype.Icon, out var iconProto))
321+
{
322+
var jobIconTexture = new TextureRect
323+
{
324+
Texture = _entMan.System<SpriteSystem>().Frame0(iconProto.Icon),
325+
TextureScale = new Vector2(2.5f, 2.5f),
326+
Stretch = TextureRect.StretchMode.KeepCentered,
327+
Margin = new Thickness(5, 0, 0, 0),
328+
};
329+
roleCheckboxContainer.AddChild(jobIconTexture);
330+
}
331+
332+
roleCheckboxContainer.AddChild(roleCheckButton);
333+
334+
roleGroupInnerContainer.AddChild(roleCheckboxContainer);
335+
336+
_roleCheckboxes.TryAdd(group, []);
337+
_roleCheckboxes[group].Add(roleCheckButton);
255338
}
256339

257340
public void UpdateBanFlag(bool newFlag)
@@ -469,7 +552,13 @@ private void SubmitButtonOnOnPressed(BaseButton.ButtonEventArgs obj)
469552
if (_roleCheckboxes.Count == 0)
470553
throw new DebugAssertException("RoleCheckboxes was empty");
471554

472-
rolesList.AddRange(_roleCheckboxes.Where(c => c is { Pressed: true, Text: { } }).Select(c => c.Text!));
555+
foreach (var button in _roleCheckboxes.Values.SelectMany(departmentButtons => departmentButtons))
556+
{
557+
if (button is { Pressed: true, Text: not null })
558+
{
559+
rolesList.Add(button.Text);
560+
}
561+
}
473562

474563
if (rolesList.Count == 0)
475564
{

Content.Client/Administration/UI/Logs/AdminLogsControl.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<Control HorizontalExpand="True"/>
5050
<Label Name="Count" Access="Public"/>
5151
<Control HorizontalExpand="True"/>
52+
<Button Name="ExportLogs" Access="Public" Text="{Loc admin-logs-export}"/>
5253
<Button Name="PopOutButton" Access="Public" Text="{Loc admin-logs-pop-out}"/>
5354
</BoxContainer>
5455
<BoxContainer Orientation="Horizontal">

0 commit comments

Comments
 (0)