Players are verified when they're in the configured Steam group (public memberslistxml, refetched every 10 minutes, kept on failure) or have an unexpired override row in gv_verified, written by the web panel. Settings and data live in CS2-SimpleAdmin's MySQL database (gv_verified, gv_settings, gv_migrations), reached through its API. - css_gv_group <groupId64|0>, css_gv_enable, css_gv_disable (@css/root): verification runs only when enabled with a group set. - css_verify <target>: why a player is or isn't verified. Admin and above (by immunity from SimpleAdmin's groups) plus Guardian, unless admin_overrides.json says otherwise. - groupverify:api (shared/GroupVerifyApi): IsVerified, GetStatus, IsActive and OnVerifiedChanged. The API object lives in the shared assembly, so it survives hot reloads of GroupVerify.
86 lines
2.9 KiB
C#
86 lines
2.9 KiB
C#
using System.ComponentModel;
|
|
using CounterStrikeSharp.API.Core;
|
|
|
|
namespace GroupVerifyApi;
|
|
|
|
/// <summary>What GroupVerify itself implements behind the API. Not for other plugins.</summary>
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public interface IGroupVerifyBackend
|
|
{
|
|
/// <summary>See <see cref="IGroupVerifyApi.IsActive"/>.</summary>
|
|
bool IsActive { get; }
|
|
|
|
/// <summary>See <see cref="IGroupVerifyApi.GetStatus"/>.</summary>
|
|
VerifyStatus GetStatus(ulong steamId64);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public sealed class GroupVerifyBridge : IGroupVerifyApi
|
|
{
|
|
/// <summary>The instance GroupVerify registers as the capability.</summary>
|
|
public static GroupVerifyBridge Instance { get; } = new();
|
|
|
|
private IGroupVerifyBackend? _backend;
|
|
|
|
private GroupVerifyBridge()
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public event Action<CCSPlayerController, VerifyStatus>? OnVerifiedChanged;
|
|
|
|
/// <inheritdoc />
|
|
public bool IsActive => _backend?.IsActive ?? false;
|
|
|
|
/// <inheritdoc />
|
|
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);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool IsVerified(ulong steamId64) => GetStatus(steamId64).Verified;
|
|
|
|
/// <inheritdoc />
|
|
public VerifyStatus GetStatus(ulong steamId64) =>
|
|
_backend is { IsActive: true } backend ? backend.GetStatus(steamId64) : default;
|
|
|
|
/// <summary>Called by GroupVerify on load.</summary>
|
|
public void Attach(IGroupVerifyBackend backend) => _backend = backend;
|
|
|
|
/// <summary>Called by GroupVerify on unload; ignored if a newer backend has attached since.</summary>
|
|
public void Detach(IGroupVerifyBackend backend)
|
|
{
|
|
if (ReferenceEquals(_backend, backend))
|
|
_backend = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
public List<Exception> RaiseVerifiedChanged(CCSPlayerController player, VerifyStatus status)
|
|
{
|
|
var errors = new List<Exception>();
|
|
foreach (var handler in OnVerifiedChanged?.GetInvocationList() ?? [])
|
|
{
|
|
try
|
|
{
|
|
((Action<CCSPlayerController, VerifyStatus>)handler)(player, status);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
errors.Add(ex);
|
|
}
|
|
}
|
|
return errors;
|
|
}
|
|
}
|