From 3c62874f9108ecce85337e166585f27c9a676f28 Mon Sep 17 00:00:00 2001 From: Astra Date: Fri, 2 Oct 2026 18:44:44 +0100 Subject: [PATCH] Verification: clan tag setting, GroupVerify 0.3.0 wording Root sets GroupVerify's clan_tag (the scoreboard tag CS2-Tags gives verified players without a rank) next to the Steam group. Validated like the plugin (12 UTF-16 units, no quotes, ; or \), saved to gv_settings and sent as css_gv_clantag when the plugin is loaded. Only changed fields are sent. GroupVerify 0.3.0 checks players with the Steam Web API as they join, so the group list is now "Confirmed group members" with first/last confirmed dates. --- README.md | 8 +++++-- internal/store/verify.go | 9 +++++--- internal/web/assets/admin.js | 28 +++++++++++++++++-------- internal/web/verify.go | 38 ++++++++++++++++++++++++++++++++-- internal/web/verify_db_test.go | 16 +++++++++++++- internal/web/verify_test.go | 20 ++++++++++++++++++ 6 files changed, 102 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 0161ace..2e4b46d 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,9 @@ verified players perks. It keeps everything in SimpleAdmin's database (`gv_verif - **Everyone** sees a "Verified" tag on the scoreboard and on player pages, but only while verification is on (enabled, with a group set) and GroupVerify isn't missing from the server's plugin list. The public site never shows why someone is verified, or who gave an override. +- **Clan tag**: Root can set the scoreboard tag verified players without a rank get (GroupVerify's + `clan_tag`, at most 12 characters). CS2-Tags (1.0.4c-zio6+) applies it, and gives unverified + players without a rank no tag at all. Blank turns it off. - **Whether it's loaded** comes from `css_plugins list` over RCON, read once a minute alongside the live status. While the server is down it's unknown, and that doesn't hide anything. - **Changes**: overrides are written to `gv_verified` and GroupVerify picks them up on its next @@ -128,8 +131,9 @@ verified players perks. It keeps everything in SimpleAdmin's database (`gv_verif - **Times** in its tables are in GroupVerify's own `timezone` setting, which the panel follows. Keep it the same as SimpleAdmin's `Timezone`. -The panel never shows a group member list from Steam itself: "Steam group members" is the list -GroupVerify last fetched and saved. +GroupVerify (0.3.0+) checks each player with the Steam Web API as they join, so "Confirmed group +members" is everyone Steam has said is in the group when they joined, not the group's full member +list. The panel never asks Steam itself. ### Name history (optional) diff --git a/internal/store/verify.go b/internal/store/verify.go index 1d20a65..3187566 100644 --- a/internal/store/verify.go +++ b/internal/store/verify.go @@ -19,6 +19,7 @@ type VerifySettings struct { GroupID string // "" when no group is set ReloadSeconds int // how often GroupVerify rereads its tables Location *time.Location + ClanTag string // scoreboard tag for verified players without a rank, "" for none } // Active matches GroupVerify: it only verifies anyone when enabled with a group set. @@ -57,6 +58,8 @@ func (s *Store) VerifySettings(ctx context.Context) (VerifySettings, error) { if n, err := strconv.Atoi(value); err == nil && n >= 10 { v.ReloadSeconds = n } + case "clan_tag": + v.ClanTag = value case "timezone": if loc, err := time.LoadLocation(value); err == nil { v.Location = loc @@ -150,7 +153,7 @@ func (s *Store) VerifyStatuses(ctx context.Context, loc *time.Location, steamids // What VerifyList lists. const ( VerifyOverrides = "overrides" // unexpired rows with override = 1 - VerifyGroup = "group" // the Steam group's members, as of GroupVerify's last fetch + VerifyGroup = "group" // players Steam confirmed are in the group as they joined ) // VerifyList lists overrides or group members, newest first. Search matches a SteamID64 or a name @@ -207,8 +210,8 @@ func (s *Store) VerifyList(ctx context.Context, loc *time.Location, kind, search return out, total, rows.Err() } -// VerifyCounts is how many group members and unexpired overrides there are, and when GroupVerify -// last saved the group's member list (nil if it never has). +// VerifyCounts is how many confirmed group members and unexpired overrides there are, and when +// Steam last confirmed a member (nil if it never has). func (s *Store) VerifyCounts(ctx context.Context, loc *time.Location) (group, overrides int, fetched *time.Time, err error) { var last sql.NullTime err = s.db.QueryRowContext(ctx, `SELECT diff --git a/internal/web/assets/admin.js b/internal/web/assets/admin.js index 797cba9..5a734c9 100644 --- a/internal/web/assets/admin.js +++ b/internal/web/assets/admin.js @@ -380,7 +380,7 @@ function verify() {
${searchBox("Search by name or SteamID64", state.query)} - ${segmented("verifyView", state.verifyView, [["overrides", "Overrides"], ["group", "Steam group members"]])} + ${segmented("verifyView", state.verifyView, [["overrides", "Overrides"], ["group", "Confirmed group members"]])}
${loading()}
`; @@ -415,16 +415,21 @@ function verifyStatus(st) {
Plugin
${PLUGIN_STATE[st.plugin](st.version)}
Steam group
${group}
-
Group members
${st.groupMembers}${st.groupFetched ? ` list saved ${fmtAgo(st.groupFetched)}` : ' never fetched'}
+
Clan tag
${st.clanTag ? `${esc(st.clanTag)} for verified players without a rank; unverified ones get none` : 'None: players keep their own tags'}
+
Group members
${st.groupMembers}${st.groupFetched ? ` last confirmed with Steam ${fmtAgo(st.groupFetched)}` : ' nobody confirmed yet'}
Overrides
${st.overrides}
Changes apply
Within ${st.reloadSeconds} seconds (times in ${esc(st.timezone)})
${st.canConfigure ? `
-