GroupVerify 0.2.0: Steam group / override verification with an API for other plugins
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.
This commit is contained in:
commit
1f61958099
13 changed files with 1711 additions and 0 deletions
81
Settings.cs
Normal file
81
Settings.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
namespace GroupVerify;
|
||||
|
||||
// The plugin's settings, from gv_settings. Immutable: a reload swaps in a new one.
|
||||
internal sealed record Settings(
|
||||
bool Enabled,
|
||||
ulong GroupId64,
|
||||
int RefreshMinutes,
|
||||
int MinForcedRefreshSeconds,
|
||||
int DbReloadSeconds,
|
||||
TimeZoneInfo TimeZone,
|
||||
string VerifyMinRank,
|
||||
string[] VerifyExtraRanks)
|
||||
{
|
||||
// Written to gv_settings when missing. The rank defaults are our real SimpleAdmin groups (see
|
||||
// the fork's Helper.StaffRanks and the web panel's site config). Only the names are set here:
|
||||
// "Admin or higher" is decided by immunity read from sa_groups.
|
||||
public static readonly (string Name, string Value)[] Defaults =
|
||||
[
|
||||
("enabled", "1"), // 0 turns verification off (css_gv_enable/css_gv_disable)
|
||||
("group_id64", "0"), // the Steam group's 64-bit ID (103582791...); 0 turns verification off (css_gv_group)
|
||||
("refresh_minutes", "10"), // how often the group's member list is fetched
|
||||
("min_forced_refresh_seconds", "60"), // css_verify refetches/reloads only when older than this
|
||||
("db_reload_seconds", "60"), // how often gv_verified and gv_settings are reread
|
||||
("timezone", "UTC"), // must match CS2-SimpleAdmin's Timezone
|
||||
("verify_min_rank", "#rank/admin"), // css_verify: this group's immunity or higher
|
||||
("verify_extra_ranks", "#rank/guardian") // css_verify: these groups too, comma-separated
|
||||
];
|
||||
|
||||
public static readonly Settings Default = Parse(new Dictionary<string, string>(), _ => { });
|
||||
|
||||
public static Settings Parse(IReadOnlyDictionary<string, string> values, Action<string> warn)
|
||||
{
|
||||
string Get(string name) =>
|
||||
values.TryGetValue(name, out var value) ? value.Trim() : Defaults.First(d => d.Name == name).Value;
|
||||
|
||||
int GetInt(string name, int min)
|
||||
{
|
||||
if (int.TryParse(Get(name), out var value) && value >= min)
|
||||
return value;
|
||||
var fallback = int.Parse(Defaults.First(d => d.Name == name).Value);
|
||||
warn($"gv_settings {name} must be a number of at least {min}; using {fallback}");
|
||||
return fallback;
|
||||
}
|
||||
|
||||
ulong groupId = 0;
|
||||
var groupText = Get("group_id64");
|
||||
if (groupText.Length > 0 && !ulong.TryParse(groupText, out groupId))
|
||||
warn($"gv_settings group_id64 \"{groupText}\" isn't a 64-bit group ID; verification is off");
|
||||
|
||||
var timeZone = TimeZoneInfo.Utc;
|
||||
var zoneName = Get("timezone");
|
||||
try
|
||||
{
|
||||
timeZone = TimeZoneInfo.FindSystemTimeZoneById(zoneName);
|
||||
}
|
||||
catch (Exception ex) when (ex is TimeZoneNotFoundException or InvalidTimeZoneException)
|
||||
{
|
||||
warn($"gv_settings timezone \"{zoneName}\" isn't a known time zone; using UTC");
|
||||
}
|
||||
|
||||
return new Settings(
|
||||
Get("enabled") != "0",
|
||||
groupId,
|
||||
GetInt("refresh_minutes", 1),
|
||||
GetInt("min_forced_refresh_seconds", 0),
|
||||
GetInt("db_reload_seconds", 10),
|
||||
timeZone,
|
||||
Get("verify_min_rank"),
|
||||
Get("verify_extra_ranks").Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
|
||||
// Verification only runs when enabled with a group set; otherwise nobody is verified.
|
||||
public bool Active => Enabled && GroupId64 != 0;
|
||||
|
||||
// Now as a wall-clock time in the database's time zone, to the second (MySQL rounds fractions).
|
||||
public DateTime Now()
|
||||
{
|
||||
var now = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZone);
|
||||
return DateTime.SpecifyKind(now.AddTicks(-(now.Ticks % TimeSpan.TicksPerSecond)), DateTimeKind.Unspecified);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue