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;
}
}