Heuristic aim detector: measures per-frame view-angle snaps around kills and flags impossible snaps and inhuman headshot ratios for admin review.
csb_aimbot_detect.sma v1.0.0
1
/*
2
* CSB Aimbot Detection
3
* Copyright (C) 2026 counter-strike-boost.com
4
*
5
* A heuristic aim-assist detector. Every frame it samples each alive player's
6
* view angle (fakemeta pev_v_angle) and measures the single-frame angular
7
* change. When a kill lands in the same frame as an impossibly large snap, a
8
* snap counter is raised; a sustained inhuman headshot ratio is a second
9
* signal. Suspects are logged with the evidence and admins are alerted. This is
10
* a heuristic aid for human review, not an automatic punisher.
11
*
12
* This program is free software: you can redistribute it and/or modify it under
13
* the terms of the GNU General Public License as published by the Free Software
14
* Foundation, either version 3 of the License, or (at your option) any later
15
* version. It is distributed in the hope that it will be useful, but WITHOUT
16
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
* FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
18
*/
19
20
#include <amxmodx>
21
#include <amxmisc>
22
#include <fakemeta>
23
24
new const PLUGIN[] = "CSB Aimbot Detection"
25
new const VERSION[] = "1.0.0"
26
new const AUTHOR[] = "counter-strike-boost.com"
27
28
new g_pEnabled, g_pSnapAngle, g_pSnapHits, g_pHsRatio, g_pMinKills
29
30
new Float:g_fLast[33][2]
31
new bool:g_bValid[33]
32
new Float:g_fFrameDelta[33]
33
34
new g_iKills[33]
35
new g_iHs[33]
36
new g_iSnapKills[33]
37
new bool:g_bFlagged[33]
38
39
public plugin_init()
40
{
41
register_plugin(PLUGIN, VERSION, AUTHOR)
42
43
g_pEnabled = register_cvar("csb_aim_enabled", "1")
44
g_pSnapAngle = register_cvar("csb_aim_snapangle", "40.0")
45
g_pSnapHits = register_cvar("csb_aim_snaphits", "4")
46
g_pHsRatio = register_cvar("csb_aim_hsratio", "90")
47
g_pMinKills = register_cvar("csb_aim_minkills", "15")
48
49
register_forward(FM_PlayerPreThink, "fwThink")
50
register_event("DeathMsg", "evDeath", "a", "1>0")
51
}
52
53
public client_putinserver(id)
54
{
55
g_bValid[id] = false
56
g_fFrameDelta[id] = 0.0
57
g_iKills[id] = 0
58
g_iHs[id] = 0
59
g_iSnapKills[id] = 0
60
g_bFlagged[id] = false
61
}
62
63
public fwThink(id)
64
{
65
if (!get_pcvar_num(g_pEnabled) || !is_user_connected(id))
66
return FMRES_IGNORED
67
68
if (is_user_bot(id) || is_user_hltv(id))
69
return FMRES_IGNORED
70
71
if (!is_user_alive(id))
72
{
73
g_bValid[id] = false
74
return FMRES_IGNORED
75
}
76
77
new Float:ang[3]
78
pev(id, pev_v_angle, ang)
79
80
if (g_bValid[id])
81
{
82
new Float:dp = ang[0] - g_fLast[id][0]
83
new Float:dy = ang[1] - g_fLast[id][1]
84
85
while (dy > 180.0) dy -= 360.0
86
while (dy < -180.0) dy += 360.0
87
while (dp > 180.0) dp -= 360.0
88
while (dp < -180.0) dp += 360.0
89
90
g_fFrameDelta[id] = floatsqroot(dp * dp + dy * dy)
91
}
92
else
93
{
94
g_bValid[id] = true
95
g_fFrameDelta[id] = 0.0
96
}
97
98
g_fLast[id][0] = ang[0]
99
g_fLast[id][1] = ang[1]
100
101
return FMRES_IGNORED
102
}
103
104
public evDeath()
105
{
106
if (!get_pcvar_num(g_pEnabled))
107
return
108
109
new killer = read_data(1)
110
new victim = read_data(2)
111
new hs = read_data(3)
112
113
if (killer < 1 || killer > 32 || killer == victim)
114
return
115
116
if (is_user_bot(killer) || is_user_hltv(killer))
117
return
118
119
g_iKills[killer]++
120
121
if (hs)
122
g_iHs[killer]++
123
124
/* snap heuristic: a very large single-frame view change on the killing frame */
125
new Float:snapAngle = get_pcvar_float(g_pSnapAngle)
126
127
if (g_fFrameDelta[killer] >= snapAngle)
128
{
129
g_iSnapKills[killer]++
130
131
log_amx("[CSB Aim] snap on kill by %N - %.1f deg in one frame (snap kills: %d)",
132
killer, g_fFrameDelta[killer], g_iSnapKills[killer])
133
134
if (!g_bFlagged[killer] && g_iSnapKills[killer] >= get_pcvar_num(g_pSnapHits))
135
flagSuspect(killer, "repeated impossible aim snaps")
136
}
137
138
/* headshot-ratio heuristic */
139
new minKills = get_pcvar_num(g_pMinKills)
140
141
if (!g_bFlagged[killer] && g_iKills[killer] >= minKills)
142
{
143
new pct = (g_iHs[killer] * 100) / g_iKills[killer]
144
145
if (pct >= get_pcvar_num(g_pHsRatio))
146
flagSuspect(killer, "inhuman headshot ratio")
147
}
148
}
149
150
flagSuspect(id, const reason[])
151
{
152
g_bFlagged[id] = true
153
154
new name[32], authid[35]
155
get_user_name(id, name, charsmax(name))
156
get_user_authid(id, authid, charsmax(authid))
157
158
new pct = g_iKills[id] ? (g_iHs[id] * 100) / g_iKills[id] : 0
159
160
log_amx("[CSB Aim] SUSPECT %s <%s> - %s (kills %d, hs %d = %d%%, snap kills %d)",
161
name, authid, reason, g_iKills[id], g_iHs[id], pct, g_iSnapKills[id])
162
163
/* alert online admins */
164
new players[32], num, pid
165
get_players(players, num, "ch")
166
167
for (new i = 0; i < num; i++)
168
{
169
pid = players[i]
170
171
if (get_user_flags(pid) & ADMIN_KICK)
172
client_print(pid, print_chat, "[CSB Aim] Possible aimbot: %s (%s). Please review.", name, reason)
173
}
174
}
175









