/*
* CSB Aimbot Detection
* Copyright (C) 2026 counter-strike-boost.com
*
* A heuristic aim-assist detector. Every frame it samples each alive player's
* view angle (fakemeta pev_v_angle) and measures the single-frame angular
* change. When a kill lands in the same frame as an impossibly large snap, a
* snap counter is raised; a sustained inhuman headshot ratio is a second
* signal. Suspects are logged with the evidence and admins are alerted. This is
* a heuristic aid for human review, not an automatic punisher.
*
* 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
#include
#include
new const PLUGIN[] = "CSB Aimbot Detection"
new const VERSION[] = "1.0.0"
new const AUTHOR[] = "counter-strike-boost.com"
new g_pEnabled, g_pSnapAngle, g_pSnapHits, g_pHsRatio, g_pMinKills
new Float:g_fLast[33][2]
new bool:g_bValid[33]
new Float:g_fFrameDelta[33]
new g_iKills[33]
new g_iHs[33]
new g_iSnapKills[33]
new bool:g_bFlagged[33]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
g_pEnabled = register_cvar("csb_aim_enabled", "1")
g_pSnapAngle = register_cvar("csb_aim_snapangle", "40.0")
g_pSnapHits = register_cvar("csb_aim_snaphits", "4")
g_pHsRatio = register_cvar("csb_aim_hsratio", "90")
g_pMinKills = register_cvar("csb_aim_minkills", "15")
register_forward(FM_PlayerPreThink, "fwThink")
register_event("DeathMsg", "evDeath", "a", "1>0")
}
public client_putinserver(id)
{
g_bValid[id] = false
g_fFrameDelta[id] = 0.0
g_iKills[id] = 0
g_iHs[id] = 0
g_iSnapKills[id] = 0
g_bFlagged[id] = false
}
public fwThink(id)
{
if (!get_pcvar_num(g_pEnabled) || !is_user_connected(id))
return FMRES_IGNORED
if (is_user_bot(id) || is_user_hltv(id))
return FMRES_IGNORED
if (!is_user_alive(id))
{
g_bValid[id] = false
return FMRES_IGNORED
}
new Float:ang[3]
pev(id, pev_v_angle, ang)
if (g_bValid[id])
{
new Float:dp = ang[0] - g_fLast[id][0]
new Float:dy = ang[1] - g_fLast[id][1]
while (dy > 180.0) dy -= 360.0
while (dy < -180.0) dy += 360.0
while (dp > 180.0) dp -= 360.0
while (dp < -180.0) dp += 360.0
g_fFrameDelta[id] = floatsqroot(dp * dp + dy * dy)
}
else
{
g_bValid[id] = true
g_fFrameDelta[id] = 0.0
}
g_fLast[id][0] = ang[0]
g_fLast[id][1] = ang[1]
return FMRES_IGNORED
}
public evDeath()
{
if (!get_pcvar_num(g_pEnabled))
return
new killer = read_data(1)
new victim = read_data(2)
new hs = read_data(3)
if (killer < 1 || killer > 32 || killer == victim)
return
if (is_user_bot(killer) || is_user_hltv(killer))
return
g_iKills[killer]++
if (hs)
g_iHs[killer]++
/* snap heuristic: a very large single-frame view change on the killing frame */
new Float:snapAngle = get_pcvar_float(g_pSnapAngle)
if (g_fFrameDelta[killer] >= snapAngle)
{
g_iSnapKills[killer]++
log_amx("[CSB Aim] snap on kill by %N - %.1f deg in one frame (snap kills: %d)",
killer, g_fFrameDelta[killer], g_iSnapKills[killer])
if (!g_bFlagged[killer] && g_iSnapKills[killer] >= get_pcvar_num(g_pSnapHits))
flagSuspect(killer, "repeated impossible aim snaps")
}
/* headshot-ratio heuristic */
new minKills = get_pcvar_num(g_pMinKills)
if (!g_bFlagged[killer] && g_iKills[killer] >= minKills)
{
new pct = (g_iHs[killer] * 100) / g_iKills[killer]
if (pct >= get_pcvar_num(g_pHsRatio))
flagSuspect(killer, "inhuman headshot ratio")
}
}
flagSuspect(id, const reason[])
{
g_bFlagged[id] = true
new name[32], authid[35]
get_user_name(id, name, charsmax(name))
get_user_authid(id, authid, charsmax(authid))
new pct = g_iKills[id] ? (g_iHs[id] * 100) / g_iKills[id] : 0
log_amx("[CSB Aim] SUSPECT %s <%s> - %s (kills %d, hs %d = %d%%, snap kills %d)",
name, authid, reason, g_iKills[id], g_iHs[id], pct, g_iSnapKills[id])
/* alert online admins */
new players[32], num, pid
get_players(players, num, "ch")
for (new i = 0; i < num; i++)
{
pid = players[i]
if (get_user_flags(pid) & ADMIN_KICK)
client_print(pid, print_chat, "[CSB Aim] Possible aimbot: %s (%s). Please review.", name, reason)
}
}