using System.ComponentModel; using CounterStrikeSharp.API.Core; namespace GroupVerifyApi; /// What GroupVerify itself implements behind the API. Not for other plugins. [EditorBrowsable(EditorBrowsableState.Never)] public interface IGroupVerifyBackend { /// See . bool IsActive { get; } /// See . VerifyStatus GetStatus(ulong steamId64); } /// /// The one API object, living in this shared assembly so it outlives GroupVerify reloads: CSS keeps /// the first capability supplier registered forever, and subscribers keep their handlers here. /// GroupVerify attaches its backend on load and detaches it on unload. Not for other plugins. /// [EditorBrowsable(EditorBrowsableState.Never)] public sealed class GroupVerifyBridge : IGroupVerifyApi { /// The instance GroupVerify registers as the capability. public static GroupVerifyBridge Instance { get; } = new(); private IGroupVerifyBackend? _backend; private GroupVerifyBridge() { } /// public event Action? OnVerifiedChanged; /// public bool IsActive => _backend?.IsActive ?? false; /// public bool IsVerified(CCSPlayerController player) { if (player is not { IsValid: true, IsBot: false, IsHLTV: false }) return false; var steamId = player.AuthorizedSteamID?.SteamId64; return steamId != null && IsVerified(steamId.Value); } /// public bool IsVerified(ulong steamId64) => GetStatus(steamId64).Verified; /// public VerifyStatus GetStatus(ulong steamId64) => _backend is { IsActive: true } backend ? backend.GetStatus(steamId64) : default; /// Called by GroupVerify on load. public void Attach(IGroupVerifyBackend backend) => _backend = backend; /// Called by GroupVerify on unload; ignored if a newer backend has attached since. public void Detach(IGroupVerifyBackend backend) { if (ReferenceEquals(_backend, backend)) _backend = null; } /// /// Called by GroupVerify on the game thread. Each handler runs on its own, so one that throws /// doesn't stop the others; the exceptions are returned for GroupVerify to log. /// public List RaiseVerifiedChanged(CCSPlayerController player, VerifyStatus status) { var errors = new List(); foreach (var handler in OnVerifiedChanged?.GetInvocationList() ?? []) { try { ((Action)handler)(player, status); } catch (Exception ex) { errors.Add(ex); } } return errors; } }