/*
* CSB SteamID Validator
* Copyright (C) 2026 counter-strike-boost.com
*
* Validates authentication at client_authorized: rejects pending IDs past a
* timeout, LAN/no-steam tokens, malformed STEAM_x:y:z strings and duplicate
* SteamIDs, with a cvar to allow or kick no-steam clients.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version. It is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See for details.
*/
#include
new const PLUGIN[] = "CSB SteamID Validator"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
#define TASK_BASE 10000
new g_pEnabled, g_pAllowNoSteam, g_pPendingTimeout, g_pBlockDup
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_steamid_enabled", "1")
g_pAllowNoSteam = register_cvar("csb_steamid_allow_nosteam", "0")
g_pPendingTimeout = register_cvar("csb_steamid_pending_timeout", "30")
g_pBlockDup = register_cvar("csb_steamid_block_dup", "1")
}
public client_authorized(id)
{
if (!get_pcvar_num(g_pEnabled) || is_user_bot(id) || is_user_hltv(id))
return
new authid[40]
get_user_authid(id, authid, charsmax(authid))
// still resolving -> re-check after the timeout
if (!authid[0] || equal(authid, "STEAM_ID_PENDING"))
{
set_task(float(get_pcvar_num(g_pPendingTimeout)), "taskPending", TASK_BASE + id)
return
}
validate(id, authid)
}
public taskPending(taskid)
{
new id = taskid - TASK_BASE
if (id < 1 || id > 32 || !is_user_connected(id))
return
new authid[40]
get_user_authid(id, authid, charsmax(authid))
validate(id, authid)
}
validate(id, const authid[])
{
// still pending or an obvious no-steam / LAN token
if (!authid[0]
|| equal(authid, "STEAM_ID_PENDING")
|| equal(authid, "VALVE_ID_PENDING")
|| equal(authid, "STEAM_ID_LAN")
|| equal(authid, "VALVE_ID_LAN")
|| equal(authid, "HLTV"))
{
if (get_pcvar_num(g_pAllowNoSteam))
return
drop(id, authid, "no valid Steam ID")
return
}
if (!isSteamFormat(authid))
{
if (get_pcvar_num(g_pAllowNoSteam))
return
drop(id, authid, "malformed Steam ID")
return
}
if (get_pcvar_num(g_pBlockDup) && isDuplicate(id, authid))
{
drop(id, authid, "duplicate Steam ID")
return
}
}
bool:isSteamFormat(const s[])
{
// expect STEAM_x:y:z
if (strlen(s) < 11)
return false
if (!equal(s, "STEAM_", 6))
return false
new colons = 0
for (new i = 6; s[i]; i++)
{
if (s[i] == ':')
colons++
else if (s[i] < '0' || s[i] > '9')
return false
}
return colons == 2
}
bool:isDuplicate(id, const authid[])
{
new players[32], num
get_players(players, num)
for (new i = 0; i < num; i++)
{
new pid = players[i]
if (pid == id || is_user_bot(pid) || is_user_hltv(pid))
continue
new other[40]
get_user_authid(pid, other, charsmax(other))
if (equal(other, authid))
return true
}
return false
}
drop(id, const authid[], const reason[])
{
new name[32], ip[24]
get_user_name(id, name, charsmax(name))
get_user_ip(id, ip, charsmax(ip), 1)
log_amx("[CSB SteamID] rejecting %s (%s) <%s>: %s", name, ip, authid, reason)
server_cmd("kick #%d ^"CSB: %s^"", get_user_userid(id), reason)
server_exec()
}