using System.Collections.Immutable; using System.Net; using Content.Server.IP; 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; } return player.HWId is { Length: > 0 } hwIdVar && ban.HWId != null && hwIdVar.AsSpan().SequenceEqual(ban.HWId.Value.AsSpan()); } /// /// 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 hardware ID of the player. /// public ImmutableArray? HWId; /// /// 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; } }