Daemon666 / CSB Wallhack Blocker Publiczny

Server-side ESP/wallhack protection: hides enemies from a client's packet unless there is a real line of sight.

v1.0.0 135 pobrań GPL-3.0 Ostatnia aktualizacja Aug 24, 2026
csb_wallhack_blocker.sma v1.0.0 127 wierszy · 3.9 KB Surowy
1 /*
2 * CSB Wallhack Blocker
3 * Copyright (C) 2026 counter-strike-boost.com
4 *
5 * Server-side wallhack / ESP protection. In FM_AddToFullPack the plugin decides,
6 * per viewer, whether an enemy player entity is actually visible: it must be in
7 * the viewer's PVS and have a clear line of sight from the viewer's eyes to the
8 * target's centre or head. If neither is clear (and the target has not fired
9 * recently), the entity is dropped from that client's packet, so it cannot be
10 * seen through walls. Teammates and recently-firing enemies are always shown.
11 *
12 * Inspired by the classic AddToFullPack wall blocker approach (Fysiks /
13 * OrangeBox). Independent GPL re-implementation; no original code is reused.
14 *
15 * This program is free software: you can redistribute it and/or modify it under
16 * the terms of the GNU General Public License as published by the Free Software
17 * Foundation, either version 3 of the License, or (at your option) any later
18 * version. It is distributed in the hope that it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 * FOR A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
21 */
22
23 #include <amxmodx>
24 #include <fakemeta>
25
26 new const PLUGIN[] = "CSB Wallhack Blocker"
27 new const VERSION[] = "1.0.0"
28 new const AUTHOR[] = "counter-strike-boost.com"
29
30 new g_pEnabled, g_pGrace
31 new Float:g_fLastFire[33]
32 new g_iMaxPlayers
33
34 public plugin_init()
35 {
36 register_plugin(PLUGIN, VERSION, AUTHOR)
37
38 g_pEnabled = register_cvar("csb_wh_enabled", "1")
39 g_pGrace = register_cvar("csb_wh_firegrace", "1.2")
40
41 register_forward(FM_AddToFullPack, "fwAddToFullPack", 0)
42 register_forward(FM_EmitSound, "fwEmitSound", 0)
43
44 g_iMaxPlayers = get_maxplayers()
45 }
46
47 public client_putinserver(id)
48 {
49 g_fLastFire[id] = 0.0
50 }
51
52 /* record when a player produces a weapon sound, for the fire grace window */
53 public fwEmitSound(ent, channel, const sample[])
54 {
55 if (ent >= 1 && ent <= g_iMaxPlayers)
56 {
57 if (sample[0] == 'w' && sample[1] == 'e' && containi(sample, "weapons/") == 0)
58 g_fLastFire[ent] = get_gametime()
59 }
60
61 return FMRES_IGNORED
62 }
63
64 public fwAddToFullPack(es, e, ent, host, hostflags, player, pSet)
65 {
66 if (!get_pcvar_num(g_pEnabled))
67 return FMRES_IGNORED
68
69 /* only care about player entities being packed for a player host */
70 if (!player)
71 return FMRES_IGNORED
72
73 if (ent < 1 || ent > g_iMaxPlayers || host < 1 || host > g_iMaxPlayers)
74 return FMRES_IGNORED
75
76 if (ent == host)
77 return FMRES_IGNORED
78
79 if (!is_user_alive(host) || !is_user_alive(ent))
80 return FMRES_IGNORED
81
82 /* never hide teammates */
83 if (get_user_team(host) == get_user_team(ent))
84 return FMRES_IGNORED
85
86 /* recently fired -> position is already given away, keep visible */
87 if (get_gametime() - g_fLastFire[ent] < get_pcvar_float(g_pGrace))
88 return FMRES_IGNORED
89
90 /* must be inside the host PVS at all */
91 if (!engfunc(EngFunc_CheckVisibility, ent, pSet))
92 return FMRES_SUPERCEDE
93
94 /* eye position of the viewer */
95 static Float:fEye[3], Float:fOfs[3]
96 pev(host, pev_origin, fEye)
97 pev(host, pev_view_ofs, fOfs)
98 fEye[0] += fOfs[0]
99 fEye[1] += fOfs[1]
100 fEye[2] += fOfs[2]
101
102 /* target centre and head */
103 static Float:fTarget[3], Float:fHead[3], Float:fTOfs[3]
104 pev(ent, pev_origin, fTarget)
105 pev(ent, pev_view_ofs, fTOfs)
106
107 fHead[0] = fTarget[0] + fTOfs[0]
108 fHead[1] = fTarget[1] + fTOfs[1]
109 fHead[2] = fTarget[2] + fTOfs[2]
110
111 if (clearLine(fEye, fTarget, host) || clearLine(fEye, fHead, host))
112 return FMRES_IGNORED
113
114 /* no clear sight line -> drop from this client's packet */
115 return FMRES_SUPERCEDE
116 }
117
118 bool:clearLine(const Float:start[3], const Float:end[3], ignore)
119 {
120 engfunc(EngFunc_TraceLine, start, end, IGNORE_MONSTERS, ignore, 0)
121
122 static Float:fFrac
123 get_tr2(0, TR_flFraction, fFrac)
124
125 return (fFrac >= 1.0)
126 }
127