Web端点击类游戏如何防范自动点击器插件作弊
点击类项目防自动点击作弊可行方案
前端侧基础校验(提高作弊门槛)
- 事件真实性校验:浏览器原生用户触发的事件
isTrusted属性为true,脚本模拟触发的事件该值为false,可作为基础过滤规则。同时要校验事件流顺序:真实用户点击会按pointerdown -> mousedown -> pointerup -> mouseup -> click的顺序触发,各事件间存在合理时间差,直接触发click、跳过前置事件的请求直接判定为异常。 - 点击频率与间隔校验:人类连续点击的手速上限约为每秒7-9次,持续点击时平均速度会更低,可设置每秒8次的软阈值,超过阈值的点击不计分。同时统计连续点击的时间间隔方差:自动点击器通常为固定间隔触发,间隔方差极小(连续10次点击间隔差小于10ms基本可以判定为脚本),人手点击的间隔波动至少在几十毫秒级别,方差会明显更高。
- 点击坐标与轨迹校验:自动点击器大多点击固定坐标,真实用户点击同一按钮时,坐标会在按钮范围内存在像素级偏移,若连续5次以上点击坐标完全无偏移可判定为异常。同时可监听鼠标移动事件,若点击前从未触发过按钮区域内的鼠标移动、鼠标直接“瞬移”到按钮位置触发点击,也属于高风险特征。
- 核心逻辑防护:不要把计分变量暴露在全局作用域(你当前代码中的
counter是全局变量,用户打开控制台直接赋值即可篡改分数),将计分、校验逻辑放在闭包中避免外部直接修改,同时可对核心JS代码做混淆,增加用户篡改前端逻辑的成本。
交互层轻量校验(低体验影响)
- 随机微干扰:每隔几秒将点击按钮的位置随机偏移3-5个像素,或不定期在按钮范围内弹出需要点击的微小校验点,自动点击器按固定坐标点击会点空,无法通过校验。注意不要加入复杂验证码,避免影响正常用户体验。
- 设备特征校验:移动端场景下可读取触控事件的接触面积、按压力度参数,自动点击器的这类参数通常为0或固定值,真实触控的参数会存在自然波动。
服务端兜底校验(核心防刷手段)
所有前端校验都存在被绕过的可能,只有服务端校验才能从根本上控制作弊风险
- 点击频率硬上限:给每个用户设置合理的单位时间点击上限,比如每分钟最多300次点击,超过上限的请求直接丢弃,就算前端逻辑被篡改,也无法实现短时间内大量刷分。
- 行为序列校验:前端不要每次点击都上报“加1分”的请求,而是攒一批点击的原始数据(时间戳、坐标、事件参数)批量上报,服务端复跑前端的特征校验规则,发现异常序列直接不计分,触发高风险规则的账号可加入风控名单。
- 增长曲线校验:真实用户的分数增长为带波动的线性曲线,中间会存在停顿、休息的间隔,若账号出现短时间分数暴涨、连续数小时无间断点击等不符合人类行为的增长特征,直接标记为异常,可做分数清零或限制操作处理。
- 操作强校验:所有分数消耗、兑换类操作必须经过服务端校验,以服务端存储的用户分数为准,前端展示的分数仅做参考,避免用户篡改前端参数直接兑换奖励。
针对你当前代码的基础改造示例
以下代码加入了基础的前端防作弊逻辑,将计分变量放在闭包中避免全局篡改,加入了事件真实性、频率、间隔、坐标校验:
@import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap'); body{ background: linear-gradient(to right, #11998e, #38ef7d) } #title{ text-align: center; font-family: 'Montserrat'; font-size: 48px; font-weight: bold; user-select: none; margin-top: 2%; } #button{ margin: auto; width: 50%; height: auto; padding: 15px; text-align: center; border: 3px solid white; border-radius: 50px; font-family: 'Montserrat'; font-size: 32px; font-weight: bold; user-select: none; transition-duration: 0.1s; } #button:hover{ cursor: pointer; transition-duration: 0.1s; background-color: white; } #button:active{ transition-duration: 0.1s; transform: scale(0.9); }
<!DOCTYPE html> <html> <head> <title>This is just test</title> <link rel="stylesheet" href="clicker.css"> </head> <body> <p id="title">Clicker Test</p> <div id="button"> <span id="text">Score:</span> <span id="score">0</span> </div> <script> (() => { let counter = 0; const clickRecords = []; // 人类每秒点击上限 const MAX_CLICK_PER_SEC = 8; const button = document.getElementById('button'); const scoreEl = document.getElementById('score'); let validMouseDown = false; // 点击合法性校验 const isClickValid = (e) => { if (!e.isTrusted) return false; const now = Date.now(); // 清理1秒前的记录 while(clickRecords.length && clickRecords[0].time < now - 1000) { clickRecords.shift(); } // 频率校验 if (clickRecords.length >= MAX_CLICK_PER_SEC) return false; // 间隔方差校验 if (clickRecords.length >= 10) { const intervals = []; for(let i = 1; i < 10; i++) { intervals.push(clickRecords[i].time - clickRecords[i-1].time); } const avgInterval = intervals.reduce((a,b) => a+b, 0) / intervals.length; const variance = intervals.reduce((a,b) => a + Math.pow(b - avgInterval, 2), 0) / intervals.length; if (variance < 20) return false; } // 坐标重复校验 const last5Clicks = clickRecords.slice(-5); if (last5Clicks.length === 5 && last5Clicks.every(r => r.x === e.clientX && r.y === e.clientY)) { return false; } clickRecords.push({time: now, x: e.clientX, y: e.clientY}); return true; } // 校验完整事件流 button.addEventListener('mousedown', e => { if (e.isTrusted) validMouseDown = true; }) button.addEventListener('mouseup', e => { if (e.isTrusted) validMouseDown = false; }) button.addEventListener('click', e => { if (!validMouseDown || !isClickValid(e)) return; // 原有点击交互逻辑 button.style.width = '45%'; setTimeout(() => button.style.width = '50%', 50); counter += 1; scoreEl.innerText = counter; // 此处可添加批量上报逻辑,将clickRecords定期发送到服务端校验 }) })() </script> </body> </html>
注:没有任何方案能100%阻止刻意作弊的用户,多层校验的核心目标是把作弊成本提高到远大于作弊收益的程度,结合服务端兜底即可覆盖绝大多数作弊场景。
内容的提问来源于stack exchange,提问作者Fieryfeng
相关产品推荐
相关产品推荐

