Files
space-station-14/Content.Server/Administration/Notes/AdminNotesEui.cs
T
Pieter-Jan Briers 29b7fc4463 Stable to master (#42599)
Ban database refactor (#42495)

* Ban DB refactor seems to work at a basic level for PostgreSQL

* New ban creation API

Supports all the new functionality (multiple players/addresses/hwids/roles/rounds per ban).

* Make the migration irreversible

* Re-implement ban notifications

The server ID check is no longer done as admins may want to place bans spanning multiple rounds irrelevant of the source server.

* Fix some split query warnings

* Implement migration on SQLite

* More comments

* Remove required from ban reason

SS14.Admin changes would like this

* More missing AsSplitQuery() calls

* Fix missing ban type filter

* Fix old CreateServerBan API with permanent time

* Fix department and role ban commands with permanent time

* Re-add banhits navigation property

Dropped this on accident, SS14.Admin needs it.

* More ban API fixes.

* Don't fetch ban exemption info for role bans

Not relevant, reduces query performance

* Regenerate migrations

* Fix adminnotes command for players that never connected

Would blow up handling null player records. Not a new bug introduced by the refactor, but I ran into it.

* Great shame... I accidentally committed submodule update...

* Update GDPR scripts

* Fix sandbox violation

* Fix bans with duplicate info causing DB exceptions

Most notably happened with role bans, as multiple departments may include the same role.
2026-01-23 15:34:23 +01:00

167 lines
4.8 KiB
C#

using Content.Server.Administration.Managers;
using Content.Server.EUI;
using Content.Shared.Administration.Notes;
using Content.Shared.Database;
using Content.Shared.Eui;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Database;
using Robust.Shared.Network;
using static Content.Shared.Administration.Notes.AdminNoteEuiMsg;
namespace Content.Server.Administration.Notes;
public sealed class AdminNotesEui : BaseEui
{
[Dependency] private readonly IAdminManager _admins = default!;
[Dependency] private readonly IAdminNotesManager _notesMan = default!;
[Dependency] private readonly IPlayerLocator _locator = default!;
public AdminNotesEui()
{
IoCManager.InjectDependencies(this);
}
private NetUserId NotedPlayer { get; set; }
private string NotedPlayerName { get; set; } = string.Empty;
private bool HasConnectedBefore { get; set; }
private Dictionary<(int, NoteType), SharedAdminNote> Notes { get; set; } = new();
public override async void Opened()
{
base.Opened();
_admins.OnPermsChanged += OnPermsChanged;
_notesMan.NoteAdded += NoteModified;
_notesMan.NoteModified += NoteModified;
_notesMan.NoteDeleted += NoteDeleted;
}
public override void Closed()
{
base.Closed();
_admins.OnPermsChanged -= OnPermsChanged;
_notesMan.NoteAdded -= NoteModified;
_notesMan.NoteModified -= NoteModified;
_notesMan.NoteDeleted -= NoteDeleted;
}
public override EuiStateBase GetNewState()
{
return new AdminNotesEuiState(
NotedPlayerName,
Notes,
_notesMan.CanCreate(Player) && HasConnectedBefore,
_notesMan.CanDelete(Player),
_notesMan.CanEdit(Player)
);
}
public override async void HandleMessage(EuiMessageBase msg)
{
base.HandleMessage(msg);
switch (msg)
{
case CreateNoteRequest request:
{
if (!_notesMan.CanCreate(Player))
{
break;
}
if (string.IsNullOrWhiteSpace(request.Message))
{
break;
}
if (request.ExpiryTime is not null && request.ExpiryTime <= DateTime.UtcNow)
{
break;
}
await _notesMan.AddAdminRemark(Player, NotedPlayer, request.NoteType, request.Message, request.NoteSeverity, request.Secret, request.ExpiryTime);
break;
}
case DeleteNoteRequest request:
{
if (!_notesMan.CanDelete(Player))
{
break;
}
await _notesMan.DeleteAdminRemark(request.Id, request.Type, Player);
break;
}
case EditNoteRequest request:
{
if (!_notesMan.CanEdit(Player))
{
break;
}
if (string.IsNullOrWhiteSpace(request.Message))
{
break;
}
await _notesMan.ModifyAdminRemark(request.Id, request.Type, Player, request.Message, request.NoteSeverity, request.Secret, request.ExpiryTime);
break;
}
}
}
public async Task ChangeNotedPlayer(NetUserId notedPlayer)
{
NotedPlayer = notedPlayer;
await LoadFromDb();
}
private void NoteModified(SharedAdminNote note)
{
if (!note.Players.Contains(NotedPlayer))
return;
Notes[(note.Id, note.NoteType)] = note;
StateDirty();
}
private void NoteDeleted(SharedAdminNote note)
{
if (!note.Players.Contains(NotedPlayer))
return;
Notes.Remove((note.Id, note.NoteType));
StateDirty();
}
private async Task LoadFromDb()
{
var locatedPlayer = await _locator.LookupIdAsync((NetUserId) NotedPlayer);
NotedPlayerName = locatedPlayer?.Username ?? string.Empty;
HasConnectedBefore = locatedPlayer?.LastAddress is not null;
Notes = (from note in await _notesMan.GetAllAdminRemarks(NotedPlayer)
select note.ToShared())
.ToDictionary(sharedNote => (sharedNote.Id, sharedNote.NoteType));
StateDirty();
}
private void OnPermsChanged(AdminPermsChangedEventArgs args)
{
if (args.Player != Player)
{
return;
}
if (!_notesMan.CanView(Player))
{
Close();
}
else
{
StateDirty();
}
}
}