using System.Collections.Immutable; using System.Net; using Content.Server.IP; using Content.Shared.Database; using Robust.Shared.Network; namespace Content.Server.Database; /// /// Implements logic to match a against a player query. /// /// /// /// This implementation is used by in-game ban matching code, and partially by the SQLite database layer. /// Some logic is duplicated into both the SQLite and PostgreSQL database layers to provide more optimal SQL queries. /// Both should be kept in sync, please! /// /// public static class BanMatcher { /// /// Check whether a ban matches the specified player info. /// /// /// /// This function does not check whether the ban itself is expired or manually unbanned. /// /// /// The ban information. /// Information about the player to match against. /// True if the ban matches the provided player info. public static bool BanMatches(ServerBanDef ban, in PlayerInfo player) { var exemptFlags = player.ExemptFlags; // Any flag to bypass BlacklistedRange bans. if (exemptFlags != ServerBanExemptFlags.None) exemptFlags |= ServerBanExemptFlags.BlacklistedRange; if ((ban.ExemptFlags & exemptFlags) != 0) return false; if (!player.ExemptFlags.HasFlag(ServerBanExemptFlags.IP) && player.Address != null && ban.Address is not null && player.Address.IsInSubnet(ban.Address.Value) && (!ban.ExemptFlags.HasFlag(ServerBanExemptFlags.BlacklistedRange) || player.IsNewPlayer)) { return true; } if (player.UserId is { } id && ban.UserId == id.UserId) { return true; } switch (ban.HWId?.Type) { case HwidType.Legacy: if (player.HWId is { Length: > 0 } hwIdVar && hwIdVar.AsSpan().SequenceEqual(ban.HWId.Hwid.AsSpan())) { return true; } break; case HwidType.Modern: if (player.ModernHWIds is { Length: > 0 } modernHwIdVar) { foreach (var hwid in modernHwIdVar) { if (hwid.AsSpan().SequenceEqual(ban.HWId.Hwid.AsSpan())) return true; } } break; } return false; } /// /// A simple struct containing player info used to match bans against. /// public struct PlayerInfo { /// /// The user ID of the player. /// public NetUserId? UserId; /// /// The IP address of the player. /// public IPAddress? Address; /// /// The LEGACY hardware ID of the player. Corresponds with . /// public ImmutableArray? HWId; /// /// The modern hardware IDs of the player. Corresponds with . /// public ImmutableArray>? ModernHWIds; /// /// Exemption flags the player has been granted. /// public ServerBanExemptFlags ExemptFlags; /// /// True if this player is new and is thus eligible for more bans. /// public bool IsNewPlayer; } }