GroupVerify 0.3.0: check players with the Steam Web API as they join, clan tag for other plugins
Steam rate-limits its community member lists by IP (429), so the whole-list download is gone. Each player is checked as they join with ISteamUser/GetUserGroupList: a member's 'group' row is added or refreshed, a non-member's deleted, and when Steam won't say (private profile, bad key, outage) the database stands. A player is asked about at most once per min_forced_refresh_seconds; css_verify rechecks its targets, offline SteamIDs too. Changing the group clears the old group's rows. refresh_minutes is gone. The Web API key goes in configs/plugins/GroupVerify/GroupVerify.json (SteamWebApiKey); every other setting stays in the database. New clan_tag setting and css_gv_clantag <tag|-> (@css/root): the scoreboard tag for verified players without a rank, applied by CS2-Tags. The API gains ClanTag and OnClanTagChanged, so shared/GroupVerifyApi changes: needs a server restart.
This commit is contained in:
parent
1f61958099
commit
10e5fe9f3c
11 changed files with 436 additions and 204 deletions
77
README.md
77
README.md
|
|
@ -4,9 +4,21 @@ Marks players as **verified** when they're in our Steam group, or when staff hav
|
|||
manual override on the web panel. It gives out nothing itself: other plugins ask it through its
|
||||
API (`GroupVerifyApi`, see [For other plugins](#for-other-plugins)) and hand out their own perks.
|
||||
|
||||
Everything lives in CS2-SimpleAdmin's MySQL database, reached through SimpleAdmin's API
|
||||
(`GetConnectionString()`), so there's no config file. Needs CS2-SimpleAdmin on MySQL; on SQLite,
|
||||
or without SimpleAdmin, it logs an error and verifies nobody.
|
||||
Its data and settings live in CS2-SimpleAdmin's MySQL database, reached through SimpleAdmin's API
|
||||
(`GetConnectionString()`). Needs CS2-SimpleAdmin on MySQL; on SQLite, or without SimpleAdmin, it
|
||||
logs an error and verifies nobody. The one exception is the Steam Web API key, a secret, which goes
|
||||
in `configs/plugins/GroupVerify/GroupVerify.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"SteamWebApiKey": "<from https://steamcommunity.com/dev/apikey>",
|
||||
"ConfigVersion": 1
|
||||
}
|
||||
```
|
||||
|
||||
CSS writes that file with a blank key on first load. Fill it in, then `css_plugins reload
|
||||
GroupVerify` (or restart). Without a key nobody's group membership is checked: players already
|
||||
saved as members stay verified, overrides still work, and the log says so once.
|
||||
|
||||
## Turning it on
|
||||
|
||||
|
|
@ -15,17 +27,19 @@ verified, including players with an override, and other plugins see `IsActive ==
|
|||
install is enabled with no group, so it's off until you set one:
|
||||
|
||||
```
|
||||
css_gv_group 103582791429521408 set the group (its 64-bit ID) and fetch its members now
|
||||
css_gv_group 103582791429521408 set the group (its 64-bit ID) and check everyone online
|
||||
css_gv_group 0 clear the group: verification is off
|
||||
css_gv_group show whether it's on, the group, and how old the list is
|
||||
css_gv_group show whether it's on and the group
|
||||
css_gv_disable turn it off, keeping the group
|
||||
css_gv_enable turn it back on
|
||||
css_gv_clantag zio the scoreboard tag for verified players without a rank (- clears it)
|
||||
```
|
||||
|
||||
These need `@css/root` (an `admin_overrides.json` entry for a command changes that) and work from
|
||||
the server console and RCON. Changes are saved to `gv_settings` and take effect at once: turning
|
||||
it off tells other plugins every verified player stopped being verified, and turning it on (or
|
||||
changing the group) fetches the member list straight away.
|
||||
changing the group) checks everyone on the server with Steam straight away. Changing the group
|
||||
deletes the saved members of the old one.
|
||||
|
||||
The group ID is the number in `<groupID64>` at
|
||||
`https://steamcommunity.com/groups/<name>/memberslistxml/?xml=1`. `css_gv_group` refuses anything
|
||||
|
|
@ -33,18 +47,26 @@ that isn't a Steam group ID.
|
|||
|
||||
## How it works
|
||||
|
||||
- **Steam group.** The group's public member list
|
||||
(`https://steamcommunity.com/gid/<group_id64>/memberslistxml/?xml=1`, every `nextPageLink` page)
|
||||
is fetched off the game thread every `refresh_minutes`. A failed or empty fetch keeps the old
|
||||
list. Each good fetch is saved to `gv_verified` as `source = 'group'` rows, and the rows of
|
||||
anyone who left are deleted; at startup those rows stand in for the list until Steam answers.
|
||||
- **Steam group, checked per player as they join.** Once Steam has authorized a player, they're
|
||||
verified straight away from what the database knows, then GroupVerify asks the Steam Web API
|
||||
which groups they're in
|
||||
(`https://api.steampowered.com/ISteamUser/GetUserGroupList/v1/?key=<key>&steamid=<steamid64>`,
|
||||
off the game thread). In the group: their `source = 'group'` row is added or refreshed. Not in
|
||||
it: the row is deleted. Steam wouldn't say (a private profile, a bad key, an outage, a rate
|
||||
limit): nothing changes, what the database has stands, and the log says why. A player is asked
|
||||
about at most once per `min_forced_refresh_seconds`, so reconnecting doesn't spam Steam.
|
||||
- **Only on join.** A player who leaves the group while on the server stays verified until they
|
||||
next join (or someone runs `css_verify` on them).
|
||||
- **Overrides.** `gv_verified` is reread every `db_reload_seconds`, so web panel changes show up
|
||||
without a restart. Expired rows are ignored, and deleted on each reload.
|
||||
- **Verified** = in the group list, **or** an unexpired row with `override` = 1.
|
||||
- Online players are checked when they connect (once Steam has authorized them), after each group
|
||||
fetch, after each database reload and after each settings command. Other plugins get
|
||||
`OnVerifiedChanged` only when a player's status changes. Their state is dropped when they
|
||||
disconnect.
|
||||
- **Verified** = a `group` row (or this session's Steam answer, which wins), **or** an unexpired
|
||||
row with `override` = 1.
|
||||
- Online players are re-evaluated after each Steam answer, database reload and settings command.
|
||||
Other plugins get `OnVerifiedChanged` only when a player's status changes. Their state is
|
||||
dropped when they disconnect.
|
||||
- **Why not the clan tag?** The tag shown on the scoreboard is CS2-Tags' rank tag on our server,
|
||||
not the player's, and the group a client says it represents (`cl_clanid`) is a client setting
|
||||
anyone can set to any group. Only Steam's own answer is trusted.
|
||||
|
||||
## `css_verify` (`!verify`)
|
||||
|
||||
|
|
@ -53,10 +75,11 @@ that isn't a Steam group ID.
|
|||
(SteamID64, `STEAM_X:Y:Z` or `[U:1:N]`), which works for offline players too. No target means
|
||||
`@me`. Works from the server console.
|
||||
|
||||
If the group list or the database was last loaded more than `min_forced_refresh_seconds` ago,
|
||||
both are brought up to date first. Then the targets are re-evaluated, and the answer goes to chat:
|
||||
one line per player for up to 5 targets (verified by Steam group, override with its expiry, or
|
||||
not verified), a summary for more, and how old the group list and overrides are. Every use is
|
||||
Each target (offline SteamIDs too) is checked with Steam again, and the database reread, where
|
||||
that was last done more than `min_forced_refresh_seconds` ago. Then the targets are re-evaluated,
|
||||
and the answer goes to chat: one line per player for up to 5 targets (verified by Steam group,
|
||||
override with its expiry, or not verified, and why Steam couldn't be asked if it couldn't), a
|
||||
summary for more, and how old the overrides are. Every use is
|
||||
logged through SimpleAdmin's `LogCommand` (server log and its Discord log) and the plugin's log.
|
||||
|
||||
**Who can use it:** Admin and above, plus Guardian. A player qualifies when one of their
|
||||
|
|
@ -86,7 +109,7 @@ match SimpleAdmin's `Timezone` (as the web panel already assumes for SimpleAdmin
|
|||
| `expires_at` | `datetime NULL` | NULL = never. Expired rows are ignored, then deleted. |
|
||||
| `added_by` | `varchar(128)` | free text: who added it (`steam-group` for group rows) |
|
||||
| `created_at` | `datetime` | first added |
|
||||
| `updated_at` | `datetime` | group rows: last seen in the list |
|
||||
| `updated_at` | `datetime` | group rows: when Steam last confirmed them |
|
||||
|
||||
One row per player and source, so a manual override and a group row never overwrite each other.
|
||||
`override` is backticked in the plugin's SQL; do the same, it's close to a reserved word.
|
||||
|
|
@ -102,7 +125,8 @@ ON DUPLICATE KEY UPDATE `override` = 1, expires_at = VALUES(expires_at),
|
|||
|
||||
`NOW()` is only right if MySQL's time zone matches `timezone`; otherwise pass the time from the
|
||||
panel. To remove one: `DELETE FROM gv_verified WHERE steamid64 = ? AND source = 'manual'`. Leave
|
||||
`group` rows alone: the next fetch rewrites them, and they never verify anyone on their own.
|
||||
`group` rows alone: they verify the player, and the next Steam check as they join adds or deletes
|
||||
them.
|
||||
|
||||
### `gv_settings`
|
||||
|
||||
|
|
@ -114,12 +138,12 @@ applies at the next reload (`db_reload_seconds`), timers included.
|
|||
|------------------------------|------------------|-----------------------------------------------------------------|
|
||||
| `enabled` | `1` | `0` turns verification off (`css_gv_enable`/`css_gv_disable`) |
|
||||
| `group_id64` | `0` | the Steam group's 64-bit ID; `0` turns it off (`css_gv_group`) |
|
||||
| `refresh_minutes` | `10` | how often the member list is fetched |
|
||||
| `min_forced_refresh_seconds` | `60` | `css_verify` refreshes only data older than this |
|
||||
| `min_forced_refresh_seconds` | `60` | a player is rechecked with Steam at most this often |
|
||||
| `db_reload_seconds` | `60` | how often `gv_settings` and `gv_verified` are reread |
|
||||
| `timezone` | `UTC` | time zone of the `datetime` columns; match SimpleAdmin's |
|
||||
| `verify_min_rank` | `#rank/admin` | `css_verify` needs this group's immunity or higher |
|
||||
| `verify_extra_ranks` | `#rank/guardian` | comma-separated groups that may also use `css_verify` |
|
||||
| `clan_tag` | (blank) | scoreboard tag for verified players without a rank, max 12 |
|
||||
|
||||
## For other plugins
|
||||
|
||||
|
|
@ -135,6 +159,11 @@ Use it on the game thread:
|
|||
- `OnVerifiedChanged(player, status)`: fired when an online player becomes verified (including
|
||||
just after connecting) or stops being verified (left the group, override ran out, or
|
||||
verification was turned off). Not fired on disconnect.
|
||||
- `ClanTag`: the scoreboard tag for verified players who have no rank tag (`css_gv_clantag`, the
|
||||
`clan_tag` setting), "" when none is set or while `IsActive` is false. GroupVerify doesn't set
|
||||
tags itself; CS2-Tags (1.0.4c-zio6+) does.
|
||||
- `OnClanTagChanged()`: fired when `ClanTag` changes, including to or from "" as GroupVerify is
|
||||
turned on or off, loaded or unloaded.
|
||||
|
||||
In the other plugin, copy `GroupVerifyApi.dll` from the server's `shared/GroupVerifyApi/` (or
|
||||
`GroupVerifyApi/bin/Release/net10.0/` here) to its `lib/`, and reference it compile-only. It must
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue