A CounterStrikeSharp plugin for CS2 that filters out accounts that don't meet minimum requirements when they connect and kicks them.
Today there is no reliable way to read a player's Prime status from the server:
- There is no networked field (netvar) the server receives carrying the Prime flag.
- The classic Steam Web API method (looking for AppID
624820) only detects players who got Prime back in the CS:GO era; those who bought it after the CS2 launch show up as false negatives. That's why it isn't even attempted here.
Instead, PrimeGuard uses Steam profile signals (level, account age, playtime, bans, privacy) that in practice filter out free-to-play accounts, smurfs and freshly created accounts — which is usually the real goal behind "Prime only".
- A CS2 dedicated server with Metamod + CounterStrikeSharp.
- A Steam Web API key (free): https://steamcommunity.com/dev/apikey
- Download
PrimeGuard.dllfrom the latest release and copy it to:game/csgo/addons/counterstrikesharp/plugins/PrimeGuard/ - Start the server once: the config is auto-generated at
game/csgo/addons/counterstrikesharp/configs/plugins/PrimeGuard/PrimeGuard.json - Edit that JSON, set your
SteamWebApiKey, and restart (orcss_plugins reload PrimeGuard).
| Option | Default | Description |
|---|---|---|
SteamWebApiKey |
"" |
Required. Your key from https://steamcommunity.com/dev/apikey |
MinimumSteamLevel |
2 |
Minimum Steam level. -1 disables. |
MinimumAccountAgeDays |
30 |
Minimum account age in days. -1 disables. |
MinimumCS2HoursPlaytime |
-1 |
Minimum hours played in CS2. -1 disables. |
BlockPrivateProfile |
true |
Kick private profiles (they can't be verified). |
BlockVACBanned |
true |
Kick accounts with a VAC ban. |
BlockGameBanned |
true |
Kick accounts with a game ban. |
ImmunityAdminFlag |
@css/bypasspremiumcheck |
Admin flag that bypasses the filter. Empty to disable. |
KickMessage |
(see config) | Message shown when kicking. |
LogChecks |
true |
Log each connecting player's info to the console (handy for tuning thresholds). |
CacheMinutes |
360 |
Minutes to cache a player's lookup so reconnects don't re-query the API. 0 disables. |
NotifyAdminsOnBan |
false |
Message online admins when a VAC/game-banned player connects. |
NotifyAdminsOnPrivateProfile |
false |
Message online admins when a private-profile player connects. |
AdminNotifyFlag |
@css/generic |
Which admins receive the notifications. |
TagPrivateInTab |
false |
Show a scoreboard tag on private-profile players who aren't kicked. |
PrivateProfileTag |
[PRIVATE] |
Tag text used for private profiles. |
The default preset is Medium: it blocks bans, private profiles, accounts younger than 30 days, and Steam level below 2. CS2 hours are disabled (
-1).
Each signal can act on its own, so you don't have to auto-kick. The admin notification and the tab tag are independent of the kick checks:
- Notify admins instead of kicking a banned player: set
BlockVACBanned: false,BlockGameBanned: false,NotifyAdminsOnBan: true. Admins get a heads-up on connect; the player stays. (This is often smarter for VAC — Steam's VAC flag is true for a ban on any game, not necessarily CS2.) - Tag instead of kicking a private profile: set
BlockPrivateProfile: false,TagPrivateInTab: true. Private profiles get a[PRIVATE]scoreboard tag instead of a kick. AddNotifyAdminsOnPrivateProfile: trueto also ping admins.
The admin notification fires even when the player is also kicked, so admins always see who was flagged.
- If the Steam Web API fails or doesn't respond, the player is not kicked (the profile is treated as "unverifiable").
- If the profile is private, only the
BlockPrivateProfilecheck applies; the others (level/age/hours) are skipped because they can't be read. - The CS2 hours check only applies when game details are public.
- Admins with the immunity flag are never filtered.
| Command | Permission | Description |
|---|---|---|
css_pgcheck |
@css/generic |
Shows your own Steam info as seen by PrimeGuard, to help calibrate thresholds. |
- Lookups run on a background thread, never on the game tick — they don't affect tickrate.
- ~4 API calls per uncached connect. A Steam Web API key allows 100,000 calls/day (~25,000 connects), so even high-churn servers stay well under the limit.
- Results are cached per SteamID for
CacheMinutes(default 6h), so the same players reconnecting cost zero extra calls. Failed/incomplete lookups are never cached, so transient errors are retried on the next connect.
- CS2 is free-to-play: the playtime lookup uses
include_played_free_games=1, which is required for AppID 730 to appear for accounts that didn't purchase the game. - For a stricter "Prime only" style filter, raise the thresholds: e.g.
MinimumCS2HoursPlaytime: 10,MinimumSteamLevel: 5,MinimumAccountAgeDays: 90.