From ec12721bac3f984ef06cbc5f0683cf9997662daa Mon Sep 17 00:00:00 2001 From: Vigers Ray Date: Sat, 19 Jul 2025 12:44:38 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BA=D0=BE=D0=BB=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Administration/Commands/PardonCommand.cs | 4 +- .../Administration/Managers/BanEventsArgs.cs | 18 ++++++++ .../Administration/Managers/BanManager.cs | 45 +++++++++++++++++++ .../Administration/Managers/IBanManager.cs | 6 +++ Content.Server/Database/ServerDbBase.cs | 5 +++ Content.Server/Database/ServerDbManager.cs | 18 ++++++++ Content.Server/Database/ServerDbPostgres.cs | 32 +++++++++++++ Content.Server/Database/ServerDbSqlite.cs | 32 +++++++++++++ 8 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 Content.Server/Administration/Managers/BanEventsArgs.cs diff --git a/Content.Server/Administration/Commands/PardonCommand.cs b/Content.Server/Administration/Commands/PardonCommand.cs index ac65ef14ee..f47ba9c99b 100644 --- a/Content.Server/Administration/Commands/PardonCommand.cs +++ b/Content.Server/Administration/Commands/PardonCommand.cs @@ -1,4 +1,5 @@ using System.Text; +using Content.Server.Administration.Managers; using Content.Server.Database; using Content.Shared.Administration; using Robust.Shared.Console; @@ -16,6 +17,7 @@ namespace Content.Server.Administration.Commands { var player = shell.Player; var dbMan = IoCManager.Resolve(); + var banMan = IoCManager.Resolve(); if (args.Length != 1) { @@ -52,7 +54,7 @@ namespace Content.Server.Administration.Commands return; } - await dbMan.AddServerUnbanAsync(new ServerUnbanDef(banId, player?.UserId, DateTimeOffset.UtcNow)); + await banMan.PardonBan(shell.Player, banId, ban); // Sunrise-Edit shell.WriteLine($"Pardoned ban with id {banId}"); } diff --git a/Content.Server/Administration/Managers/BanEventsArgs.cs b/Content.Server/Administration/Managers/BanEventsArgs.cs new file mode 100644 index 0000000000..fd50c12bb8 --- /dev/null +++ b/Content.Server/Administration/Managers/BanEventsArgs.cs @@ -0,0 +1,18 @@ +using Robust.Shared.Network; + +namespace Content.Server.Administration.Managers; + +public sealed class BanIssuedEventArgs : EventArgs +{ + public NetUserId? Target { get; init; } + public NetUserId? BanningAdmin { get; init; } + public string? Reason { get; init; } + public DateTimeOffset Time { get; init; } +} + +public sealed class BanPardonedEventArgs : EventArgs +{ + public NetUserId? Target { get; init; } + public NetUserId? PardoningAdmin { get; init; } + public DateTimeOffset Time { get; init; } +} diff --git a/Content.Server/Administration/Managers/BanManager.cs b/Content.Server/Administration/Managers/BanManager.cs index 3d4baa3e19..75ef3f19f1 100644 --- a/Content.Server/Administration/Managers/BanManager.cs +++ b/Content.Server/Administration/Managers/BanManager.cs @@ -66,6 +66,8 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit private string _webhookName = "Sunrise Ban"; private string _webhookAvatarUrl = "https://i.ibb.co/WfGqKtG/avatar.png"; private List _ipWhitelist = []; + public event EventHandler? BanIssued; + public event EventHandler? BanPardoned; // Sunrise-end private readonly Dictionary> _cachedRoleBans = new(); @@ -122,6 +124,20 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit _ipWhitelist = ips; } + + public async Task PardonBan(ICommonSession? admin, int banId, ServerBanDef ban) + { + await _db.AddServerUnbanAsync(new ServerUnbanDef(banId, admin?.UserId, DateTimeOffset.UtcNow)); + if (admin != null) + { + BanPardoned?.Invoke(this, new BanPardonedEventArgs + { + Target = ban.UserId, + PardoningAdmin = admin.UserId, + Time = DateTimeOffset.UtcNow + }); + } + } // Sunrise-End private async Task CachePlayerData(ICommonSession player, CancellationToken cancel) @@ -248,6 +264,16 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit var hwidString = hwid?.ToString() ?? "null"; var expiresString = expires == null ? Loc.GetString("server-ban-string-never") : $"{expires}"; + // Sunrise-Start + BanIssued?.Invoke(this, new BanIssuedEventArgs + { + Target = target, + BanningAdmin = banningAdmin, + Reason = reason, + Time = DateTimeOffset.UtcNow + }); + // Sunrise-End + var key = _cfg.GetCVar(CCVars.AdminShowPIIOnBan) ? "server-ban-string" : "server-ban-string-no-pii"; var logMessage = Loc.GetString( @@ -368,6 +394,16 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit return; } + // Sunrise-Start + BanIssued?.Invoke(this, new BanIssuedEventArgs + { + Target = target, + BanningAdmin = banningAdmin, + Reason = reason, + Time = timeOfBan + }); + // Sunrise-End + var length = expires == null ? Loc.GetString("cmd-roleban-inf") : Loc.GetString("cmd-roleban-until", ("expires", expires)); _chat.SendAdminAlert(Loc.GetString("cmd-roleban-success", ("target", targetUsername ?? "null"), ("role", role), ("reason", reason), ("length", length))); @@ -433,6 +469,15 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit await _db.AddServerRoleUnbanAsync(new ServerRoleUnbanDef(banId, unbanningAdmin, DateTimeOffset.UtcNow)); + // Sunrise-Start + BanPardoned?.Invoke(this, new BanPardonedEventArgs + { + Target = ban.UserId, + PardoningAdmin = unbanningAdmin, + Time = DateTimeOffset.UtcNow + }); + // Sunrise-End + if (ban.UserId is { } player && _playerManager.TryGetSessionById(player, out var session) && _cachedRoleBans.TryGetValue(session, out var roleBans)) diff --git a/Content.Server/Administration/Managers/IBanManager.cs b/Content.Server/Administration/Managers/IBanManager.cs index 86b1785b7a..51957dd92d 100644 --- a/Content.Server/Administration/Managers/IBanManager.cs +++ b/Content.Server/Administration/Managers/IBanManager.cs @@ -1,6 +1,7 @@ using System.Collections.Immutable; using System.Net; using System.Threading.Tasks; +using Content.Server.Database; using Content.Shared.Database; using Content.Shared.Roles; using Robust.Shared.Network; @@ -100,4 +101,9 @@ public interface IBanManager /// /// Player's session public void SendRoleBans(ICommonSession pSession); + // Sunrise-Start + public Task PardonBan(ICommonSession? admin, int banId, ServerBanDef ban); + public event EventHandler? BanPardoned; + public event EventHandler? BanIssued; + // Sunrise-End } diff --git a/Content.Server/Database/ServerDbBase.cs b/Content.Server/Database/ServerDbBase.cs index 669d02fa05..59328406aa 100644 --- a/Content.Server/Database/ServerDbBase.cs +++ b/Content.Server/Database/ServerDbBase.cs @@ -512,6 +512,11 @@ namespace Content.Server.Database return flags ?? ServerBanExemptFlags.None; } + // Sunrise-Start + public abstract Task> GetServerBansByAdminAsync(NetUserId adminId, DateTimeOffset since); + public abstract Task DeleteServerBanAsync(int banId); + // Sunrise-End + #endregion #region Role Bans diff --git a/Content.Server/Database/ServerDbManager.cs b/Content.Server/Database/ServerDbManager.cs index b91ecc2476..f3a27224b4 100644 --- a/Content.Server/Database/ServerDbManager.cs +++ b/Content.Server/Database/ServerDbManager.cs @@ -126,6 +126,10 @@ namespace Content.Server.Database /// if the user is not exempt from any bans. Task GetBanExemption(NetUserId userId, CancellationToken cancel = default); + // Sunrise-Start + Task> GetServerBansByAdminAsync(NetUserId adminId, DateTimeOffset since); + Task DeleteServerBanAsync(int banId); + // Sunrise-End #endregion #region Role Bans @@ -584,6 +588,20 @@ namespace Content.Server.Database return RunDbCommand(() => _db.GetBanExemption(userId, cancel)); } + // Sunrise-Start + public Task> GetServerBansByAdminAsync(NetUserId adminId, DateTimeOffset since) + { + DbReadOpsMetric.Inc(); + return RunDbCommand(() => _db.GetServerBansByAdminAsync(adminId, since)); + } + + public Task DeleteServerBanAsync(int banId) + { + DbWriteOpsMetric.Inc(); + return RunDbCommand(() => _db.DeleteServerBanAsync(banId)); + } + // Sunrise-End + #region Role Ban public Task GetServerRoleBanAsync(int id) { diff --git a/Content.Server/Database/ServerDbPostgres.cs b/Content.Server/Database/ServerDbPostgres.cs index c034670837..bab54a3ea5 100644 --- a/Content.Server/Database/ServerDbPostgres.cs +++ b/Content.Server/Database/ServerDbPostgres.cs @@ -127,6 +127,38 @@ namespace Content.Server.Database return bans; } + // Sunrise-Start + public override async Task> GetServerBansByAdminAsync(NetUserId adminId, DateTimeOffset since) + { + await using var db = await GetDbImpl(); + var bans = await db.PgDbContext.Ban + .Include(b => b.Unban) + .Where(b => b.BanningAdmin == adminId.UserId && b.BanTime >= since.UtcDateTime) + .ToListAsync(); + var result = new List(); + foreach (var ban in bans) + { + var banDef = ConvertBan(ban); + if (banDef != null) + result.Add(banDef); + } + return result; + } + + public override async Task DeleteServerBanAsync(int banId) + { + await using var db = await GetDbImpl(); + var unbans = db.PgDbContext.Unban.Where(u => u.BanId == banId); + db.PgDbContext.Unban.RemoveRange(unbans); + var ban = await db.PgDbContext.Ban.SingleOrDefaultAsync(b => b.Id == banId); + if (ban != null) + { + db.PgDbContext.Ban.Remove(ban); + await db.PgDbContext.SaveChangesAsync(); + } + } + // Sunrise-End + private static IQueryable MakeBanLookupQuery( IPAddress? address, NetUserId? userId, diff --git a/Content.Server/Database/ServerDbSqlite.cs b/Content.Server/Database/ServerDbSqlite.cs index c3109ec6e6..d4fc94e32b 100644 --- a/Content.Server/Database/ServerDbSqlite.cs +++ b/Content.Server/Database/ServerDbSqlite.cs @@ -101,6 +101,38 @@ namespace Content.Server.Database return (await GetServerBanQueryAsync(db, address, userId, hwId, modernHWIds, includeUnbanned)).ToList(); } + // Sunrise-Start + public override async Task> GetServerBansByAdminAsync(NetUserId adminId, DateTimeOffset since) + { + await using var db = await GetDbImpl(); + var bans = await db.SqliteDbContext.Ban + .Include(b => b.Unban) + .Where(b => b.BanningAdmin == adminId.UserId && b.BanTime >= since.UtcDateTime) + .ToListAsync(); + var result = new List(); + foreach (var ban in bans) + { + var banDef = ConvertBan(ban); + if (banDef != null) + result.Add(banDef); + } + return result; + } + + public override async Task DeleteServerBanAsync(int banId) + { + await using var db = await GetDbImpl(); + var unbans = db.SqliteDbContext.Unban.Where(u => u.BanId == banId); + db.SqliteDbContext.Unban.RemoveRange(unbans); + var ban = await db.SqliteDbContext.Ban.SingleOrDefaultAsync(b => b.Id == banId); + if (ban != null) + { + db.SqliteDbContext.Ban.Remove(ban); + await db.SqliteDbContext.SaveChangesAsync(); + } + } + // Sunrise-End + private async Task> GetServerBanQueryAsync( DbGuardImpl db, IPAddress? address,