Daemon666 / CSB Spinbot Detection Público

Flags spinbot/anti-aim from impossible yaw rotation speed or an illegal pitch outside -89..89.

v1.0.0 150 downloads GPL-3.0 Última atualização Aug 26, 2026
csb_spinbot_detect.sma v1.0.0 122 linhas · 3.2 KB Bruto
1 /*
2 * CSB Spinbot Detection
3 * Copyright (C) 2026 counter-strike-boost.com
4 *
5 * Samples pev_v_angle each frame and flags spinbot / anti-aim: a yaw that
6 * rotates faster than a human can move the mouse, or a pitch outside the legal
7 * -89..89 range, over several sustained frames.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version. It is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
15 */
16
17 #include <amxmodx>
18 #include <fakemeta>
19
20 new const PLUGIN[] = "CSB Spinbot Detection"
21 new const VERSION[] = "1.0.0"
22 new const AUTHOR[] = "counter-strike-boost.com"
23
24 new g_pEnabled, g_pMaxYaw, g_pStrikes, g_pAction
25
26 new Float:g_fLastYaw[33]
27 new bool:g_bHasLast[33]
28 new g_iStrikes[33]
29
30 public plugin_init()
31 {
32 register_plugin(PLUGIN, VERSION, AUTHOR)
33
34 g_pEnabled = register_cvar("csb_spin_enabled", "1")
35 g_pMaxYaw = register_cvar("csb_spin_maxyaw", "50.0")
36 g_pStrikes = register_cvar("csb_spin_strikes", "10")
37 g_pAction = register_cvar("csb_spin_action", "0")
38
39 register_forward(FM_PlayerPreThink, "fwPreThink")
40 }
41
42 public client_putinserver(id)
43 {
44 g_bHasLast[id] = false
45 g_iStrikes[id] = 0
46 }
47
48 public fwPreThink(id)
49 {
50 if (!get_pcvar_num(g_pEnabled) || !is_user_alive(id) || is_user_bot(id))
51 return FMRES_IGNORED
52
53 new Float:angles[3]
54 pev(id, pev_v_angle, angles)
55
56 new bool:bad = false
57 new reason[24]
58
59 // legal pitch is clamped to [-89, 89]; anything beyond is a hack angle
60 if (angles[0] > 89.5 || angles[0] < -89.5)
61 {
62 bad = true
63 copy(reason, charsmax(reason), "illegal pitch")
64 }
65 else if (g_bHasLast[id])
66 {
67 new Float:delta = angles[1] - g_fLastYaw[id]
68
69 // normalise to the shortest signed turn
70 while (delta > 180.0) delta -= 360.0
71 while (delta < -180.0) delta += 360.0
72
73 if (delta < 0.0)
74 delta = -delta
75
76 if (delta > get_pcvar_float(g_pMaxYaw))
77 {
78 bad = true
79 copy(reason, charsmax(reason), "impossible yaw speed")
80 }
81 }
82
83 g_fLastYaw[id] = angles[1]
84 g_bHasLast[id] = true
85
86 if (bad)
87 {
88 g_iStrikes[id]++
89
90 if (g_iStrikes[id] >= get_pcvar_num(g_pStrikes))
91 {
92 flag(id, reason)
93 g_iStrikes[id] = 0
94 }
95 }
96 else if (g_iStrikes[id] > 0)
97 {
98 g_iStrikes[id]--
99 }
100
101 return FMRES_IGNORED
102 }
103
104 flag(id, const reason[])
105 {
106 new name[32], authid[35]
107 get_user_name(id, name, charsmax(name))
108 get_user_authid(id, authid, charsmax(authid))
109
110 log_amx("[CSB Spinbot] %s <%s> flagged: %s", name, authid, reason)
111
112 if (get_pcvar_num(g_pAction) == 1)
113 {
114 server_cmd("kick #%d ^"CSB: spinbot / anti-aim detected^"", get_user_userid(id))
115 server_exec()
116 }
117 else
118 {
119 client_print(0, print_chat, "[CSB] %s is suspected of using spinbot / anti-aim (%s).", name, reason)
120 }
121 }
122