passer au contenu principal
paste
bin
.ca
type · paste · share
⌘
K
Famille
La famille bin
pastebin.ca
pôle
Share text and code with expiry and privacy controls.
imagebin.ca
Upload and share images with direct links.
filebin.ca
Drop a file and get a shareable link.
notebin.ca
Write Markdown notes with durable links.
turl.ca
Short, reputation-checked links.
attn.ca
Notifications and alerts for your services.
voicebin.ca
Record and share short voice clips.
dnsbin.ca
Inspect DNS and debug records.
Docs
Se connecter
?
← retour au collage
›
Modifier / dupliquer
Collage sans titre
#244GAVtWWF
public / public
nouvelle version
anonyme
créé 7 days ago
Expire dans 4 hours
10.8 KB
syntaxe:
text
Vos changements créent un nouveau collage lié à celui-ci — l’original reste intact.
nouvelle version
Vos changements créent un nouveau collage lié à celui-ci — l’original reste intact.
Titre (facultatif)
Nom de fichier
Syntaxe
text
text
bash
c
cpp
css
diff
dockerfile
go
html
ini
java
javascript
json
kotlin
lua
makefile
markdown
nginx
php
python
ruby
rust
shellscript
sql
swift
toml
typescript
xml
yaml
Visibilité
Fil public
Accès
public
Expire
7 jours
10 min
1 heure
1 jour
7 jours
30 jours
90 jours
personnalisé…
Expiration personnalisée
Note de changement
(facultatif)
Ce collage sera affiché dans le fil public. Changez la visibilité si vous voulez seulement le partager par lien.
Créer une nouvelle version
Annuler
Collez ou tapez…
问题一:getY() 判断了两次——复制粘贴 bug,出现在 6 个文件 先看 [RotationEvent.java](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/api/events/RotationEvent.java) 里 getAbsDelta() 的定义,后面都用得上: public static double absDelta(float v1, float v2) { return Math.abs(Math.abs(v1) - Math.abs(v2)); // 两个绝对值的差再取绝对值 } public Vec2f getDelta() { return new Vec2f(to.getX() - from.getX(), to.getY() - from.getY()); // 有符号增量 } public Vec2f getAbsDelta() { return new Vec2f(absDelta(to.getX(), from.getX()), absDelta(to.getY(), from.getY())); } 然后这行代码原样出现在 6 个组件的入口: [AimBasicCheck.java (line 30)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimBasicCheck.java:30) public void process(final RotationEvent event) { if (check.getProfile().ignoreCinematic()) return; if (event.getAbsDelta().getY() == 0 && event.getAbsDelta().getY() == 0) return; // ← 两个 getY() this.rawRotations.add(new Vec2(event.getTo().getX(), event.getTo().getY())); 同样写法出现在 [AimConstantCheck.java (line 45)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimConstantCheck.java:45)、[AimInvalidCheck.java (line 37)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimInvalidCheck.java:37)、[AimInconsistentCheck.java (line 42)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimInconsistentCheck.java:42)、[AimPatternCheck.java (line 44)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimPatternCheck.java:44)、[AimSmoothCheck.java (line 37)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimSmoothCheck.java:37)。 问题本质:意图显然是"该 tick 完全没有旋转就跳过",即 getX() == 0 && getY() == 0。但实际只检查了 Y 两次,语义变成"pitch 没变就跳过"。于是: Δyaw ≠ 0、Δpitch = 0(纯水平转动鼠标):被错误丢弃; Δyaw = 0、Δpitch ≠ 0(纯上下看):照常进入检测; pitch 从 -1° 转到 +1° 这类跨过 0 点的移动,因为 |abs(-1) - abs(1)| = 0 也会被误判为"没旋转"。 影响:这 6 个组件采集到的旋转序列整体缺失了"水平-only"样本。对 [AimConstantCheck](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimConstantCheck.java) 这类依赖相邻 tick 增量做 GCD 的检查,跳过的 tick 会让"相邻"变成不相邻,GCD 计算结果直接失真;对 Smooth(平滑角)、Basic(机器化计数)则是检测证据缺失。而且同一行 bug 复制了 6 份,说明是初版手误后一直没被发现——这类守卫代码的错误最难排查,因为系统"看起来还能跑"。 问题二:AimPatternCheck 里 X 轴和 Y 轴混用 [AimPatternCheck.java (line 55)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/heuristic/AimPatternCheck.java:55) final Vec2f delta = event.getDelta(); final float yawFactor = delta.getX() - oldDelta.getX(); // 本 tick 与上 tick 的 yaw 增量之差 final float pitchFactor = delta.getY() - oldDelta.getY(); // 同理 pitch final Vec2f vec = new Vec2f(yawFactor, pitchFactor); this.sample.add(vec); ... for (int i = 0; i < SAMPLE_SIZE; i++) if (i > 0 && Math.abs(this.sample.get(i).getX()) > 1.0) { rawPatterns.add(Math.abs(this.sample.get(i).getX() - this.sample.get(i - 1).getY())); // ^^^^^^^^^^^^ ^^^^^^^^^^^^ // 当前 tick 的 X 减去 上一 tick 的 Y } for (final float x : rawPatterns) if (x < 1e-4) filteredPatterns.add(x); if (filteredPatterns.size() > 3) { flagged = true; // → "Suspicious patterns" rawPatterns 收集的应该是"同一轴二阶差分",即 X(i) - X(i-1)(或 Y-Y),也就是增量变化量是否恒定——恒定说明 bot 的平滑是固定步长。实际写成了 X(i) - Y(i-1):当前 tick 的 yaw 增量减上一 tick 的 pitch 增量,两个物理意义不同的量相减。 影响: 正常"水平匀速微调"的 bot(X 恒定、Y≈0)被漏掉:X(i) - Y(i-1) = a - 0 = a,进不了 < 1e-4 过滤; 反而"对角线匀速移动"的 bot(X 和 Y 每 tick 增量恰好相同)会意外命中:X(i) - Y(i-1) = a - a = 0; 过滤门槛 Math.abs(sample[i].X) > 1.0 只看 X,pitch 主导的移动基本进不来。 所以这个检测器名义上叫 pattern 检测,实际只剩一个"yaw 与上一 tick pitch 相关性"的残缺版本,横竖都不对——它是"歪打正着"型 bug。 问题三:灵敏度估计里 lastDeltaPitch 永远是 0(空操作赋值) 先看调用处 [RawMovementListener.java (line 88)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/listeners/RawMovementListener.java:88): if (hasRotation) { SensitivityProcessor controller = profile.getSensitivityProcessor(); controller.setLastDeltaPitch(controller.getLastDeltaPitch()); // ← 读出来再原样写回去,no-op Vec2f from = new Vec2f(profile.getFrom().getYaw(), profile.getFrom().getPitch()); Vec2f to = new Vec2f(profile.getTo().getYaw(), profile.getTo().getPitch()); RotationEvent rotationEvent = new RotationEvent(profile, to, from); controller.setDeltaPitch(rotationEvent.getDelta().getY()); // 下一行才写入"本次" pitch delta controller.processSensitivity(); setLastDeltaPitch(getLastDeltaPitch()) 是"自己赋值给自己"。正确的意图应该是把上一 tick 的 deltaPitch 存进 lastDeltaPitch(在覆盖前先转移),即: controller.setLastDeltaPitch(controller.getDeltaPitch()); controller.setDeltaPitch(rotationEvent.getDelta().getY()); 由于这个赋值被写成空操作,lastDeltaPitch 从初始值 0 开始就再也没变过。再看消费它的 [SensitivityProcessor.java (line 130)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/api/player/SensitivityProcessor.java:130): public static double getGcd(final double a, final double b) { if (Math.abs(b) < 0.001 || a == b) { return a; // b≈0 时直接返回 a } ... } public void processSensitivity() { ... final float gcd = (float) getGcd(this.deltaPitch, this.lastDeltaPitch); // lastDeltaPitch 恒为 0 final double sensitivityModifier = Math.cbrt(0.8333 * gcd); final double sensitivityStepTwo = 1.666 * sensitivityModifier - 0.3333; final double finalSensitivity = sensitivityStepTwo * 200.0; 推演后果:getGcd(deltaPitch, 0) 直接返回 deltaPitch。也就是说: 设计上应该取"相邻两次 pitch 增量的 GCD"(即最小鼠标步长),实际退化成单样本反推——每 tick 都假设这次移动恰好等于一个鼠标步长; 真实玩家一次移动 k 个像素时,cbrt(k·step) 会把估计值放大 ∛k 倍,灵敏度估计系统性偏高; deltaPitch = 0 时 gcd = 0,cbrt(0) = 0,finalSensitivity = -66.7,负值样本混进 40 样本的众数统计,进一步污染结果。 影响:灵敏度是整套检测的地基——熵检查要求 sens 60–150、Inconsistent 要求 75–175、AimConstantCheck 要排除低灵敏度。估计值失真会同时造成两类后果:该检测的窗口被跳过(漏检),不该检测的玩家被纳入(误报)。唯一遮羞布是上面那段独立的"严格路径"(|deltaPitch| < 0.31 时直接对照 MCP 灵敏度表,不依赖 lastDeltaPitch),所以系统没有完全失效,bug 也因此很难暴露。 问题四:AimStatisticsCheck 的 Shannon 熵分支被注释掉了(死代码) [AimStatisticsCheck.java (line 120)](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/checks/aim/AimStatisticsCheck.java:120) final double kTest = Statistics.kolmogorovSmirnovTest(Statistics.getJiffDelta(x, 6), Function.identity()); { // Kolmogorov Smirnov Test if (kTest > 10 && Math.abs(Statistics.getAverage(x)) < 13) { total++; } } shannonAnalysis.add(Statistics.getShannonEntropy(jiffYaw)); if (shannonAnalysis.size() > 9) { final Set<Double> uniq = new HashSet<>(shannonAnalysis); final double diff = getDifference(Statistics.getMin(uniq), Statistics.getMax(uniq)); if (uniq.size() <= 5 && uniq.size() > 3 && diff < 0.38) { // this.profile.punish("Aim", "[Statistics] AimBot Entropy Heuristic " + uniq.size() + " " + diff, 3.0f); } shannonAnalysis.clear(); } 问题:这段代码设计了一个"熵启发式"——对 jiff-5 后的 yaw 增量算 Shannon 熵,累积 10 个窗口后检查:去重后只剩 4–5 个不同熵值、且最大最小值差距 < 0.38,说明熵异常稳定,疑似 bot。但唯一的动作 profile.punish(...) 被整行注释,整个 if 分支什么都不做。后果: 每个 25-tick 窗口都要对 5 层 jiff 差分结果算熵、建 HashSet,纯浪费 CPU,产出为 0; 注释掉的调用签名是 3 参(punish(check, info, vl)),而当前 [PlayerProfile.punish](C:/Users/Administrator/Documents/Codex/2026-08-02/fen-x/work/mx-src/MX-Project-master/src/main/java/kireiko/dev/anticheat/api/player/PlayerProfile.java) 签名是 punish(check, component, info, vl)——即使取消注释也无法编译,说明这是早期版本遗留; 上面的 KS 检验是启用的,所以这不是"整块没做完",而是单独把熵检测关了——很可能是当时误报太高被作者手动注释掉,但留下了执行一半的框架。 小结 这四个问题里,问题一和问题三是"系统级"的:一个让 6 个组件持续丢样本,一个让灵敏度估计从设计意图退化成了近似值,都会静默影响检测精度和误报率,且不报错。问题二是单点逻辑错误,检测语义被偷换。问题四则是功能被关闭后的残留死代码。如果我要给修复建议,优先级是:问题一改成 getX()==0 && getY()==0(或直接删掉守卫让各组件自己处理零样本)、问题三把空操作改成先存旧值再写新值,然后问题二统一成同轴差分,问题四要么恢复(补上 component 参数)要么删掉整段。需要的话我可以直接给出修复后的 diff。 8:44 AM