反作弊
豁免从哪来 · 各环境窗口差异 · 返回总条目
拉弓包生效后能拿到一段检测豁免,来源是服务端手上的使用物品状态在同一 tick 内被重置过,释放与位移都按新状态结算。这一段窗口有多长、被哪些检测覆盖,取决于服务端与反作弊的实现;GrimAC 貌似已经有针对这个发包序列的检测。
豁免从哪来
三条同时成立,才会出现这段窗口:
- 状态被重置。重发的
C08让服务端重新startUsingItem(),它自己那份getTicksUsingItem()归零。紧接着到达的释放看到的是一个刚开始的计时。 - 释放被单独结算。半个
C07算出的力度低于 0.1,这一帧不生成箭矢;补射发生在窗口内的回发之后,与这一次释放不在同一个结算点上。 - 位移按新状态处理。同一 tick 里跟着上来的
C04族让服务端认为玩家仍在正常移动,没有出现“拉满两次却只结算一次”的累积。
换句话说,豁免不是绕过某一项检查,而是服务端自己看到的状态序列本来就自洽:先开始使用、再释放、再移动。检测器要发现异常,得把这几帧拼回同一个 tick 才有可能。
各环境的差别
差别集中在两件事:一个 tick 内的连续包怎么排队,以及检测器拿到的是原始包还是处理后的状态。
| 环境 | 处理方式 | 对拉弓包的影响 |
|---|---|---|
| 原版服务端 | 按到达顺序进主线程队列,逐个处理,不合并 | 顺序成立就成立,没有额外判定 |
| Grim | 在包层做预测与比对,关注位移与使用物品的时序 | 貌似已经有针对这个发包序列的检测,见下 |
| Matrix | 基于位移预测与重力推演 | 关注位移是否符合物理,对同一 tick 的包序不敏感 |
| ACA | 启发式规则集合,按动作组合打分 | 组合命中与否取决于规则覆盖 |
| Polar | 服务端侧校验与事务性检查 | 对序号往返的配对更敏感 |
| Ersa | 以行为序列为主 | 窗口越短越难拼出完整序列 |
这也是为什么同一套发送节奏在某些环境成立、在另一些不成立:差别不在客户端,而在服务端把这几帧拼起来的方式。
注意:GrimAC 貌似已经有针对这个发包序列的检测,实际使用时需要注意。它的判定点在包层,正好覆盖“同一 tick 内先重置再释放”这个组合。
怎么自查
- 先记时间。每次发包记下客户端 tick 与墙钟时间,抓包对照,确认几个包确实落在同一 tick。
- 分离变量。先只发
C08与C07,确认这一轮不生成箭矢;再加回发与位移,看哪一步开始出现异常判定。 - 看日志而不是猜。服务端侧看反作弊的告警与回拉记录,客户端侧看是否收到
S08。两侧时间戳对齐后再判断。