• 欢迎加入MineBBS QQ讨论群:点击查看所有的官方讨论群
  • 我们将于近期对服务器进行迁移,服务可能中断至多2日。请各位安排好自己的访问计划,造成不便敬请谅解!
  • MineBBS入站考试已经上线!想要成为【正式会员】解锁更多功能吗?快来参与吧!【点我去看】

已解决 求算法

zbldyyds

【Lv:4】

VIP
正式会员
注册
2025/05/25
消息
577
金粒
407.25金粒
我在做一个反作弊
但是我现在的算法会误识别跑跳的玩家
而在天上飞的g哥却啥事没有
现在想在论坛上找找思路
有人知道怎么才能精准识别g哥吗
 
解决方案
[MD] 呃,首先我不知道你是用哪种API,所以下面就用我最熟悉的基岩版SAPI为例: 对于玩家对象有以下的基础API: - `location: Vector3` - 当前位置 - `getVelocity(): Vector3` - 当前速度向量 - `isOnGround: boolean` - 是否在地面 - `isFalling: boolean` - 是否在下落 - `isClimbing: boolean` - 是否在攀爬 - `isInWater: boolean` - 是否在水中 - `isSwimming: boolean` - 是否在游泳 - `isGliding: boolean` - 是否用鞘翅滑翔 - `isFlying: boolean` - 是否在飞行(创造/旁观模式) - `isJumping: boolean` - 是否在跳跃 - `isSprinting: boolean` - 是否在冲刺 - `getGameMode(): GameMode` - 游戏模式 - `getBlockStandingOn()` - 获取站立的方块 通常来说,极度精确的检测是不太可能的。常规的标准方案是利用**多层级置信度累积模型**(AI时代这个东西已经很常见了吧),从即时触发到长期行为分析,分级处理: 首先呢,可以对一些白名单进行剔除(这个白名单是AI生成的): | 条件 | API | 逻辑 | |------|-----|------| | 创造/旁观模式 | `player.getGameMode()` | 返回 `creative` 或 `spectator` → 跳过 | | 鞘翅滑翔 | `player.isGliding` |...[/MD]
[MD] 呃,首先我不知道你是用哪种API,所以下面就用我最熟悉的基岩版SAPI为例: 对于玩家对象有以下的基础API: - `location: Vector3` - 当前位置 - `getVelocity(): Vector3` - 当前速度向量 - `isOnGround: boolean` - 是否在地面 - `isFalling: boolean` - 是否在下落 - `isClimbing: boolean` - 是否在攀爬 - `isInWater: boolean` - 是否在水中 - `isSwimming: boolean` - 是否在游泳 - `isGliding: boolean` - 是否用鞘翅滑翔 - `isFlying: boolean` - 是否在飞行(创造/旁观模式) - `isJumping: boolean` - 是否在跳跃 - `isSprinting: boolean` - 是否在冲刺 - `getGameMode(): GameMode` - 游戏模式 - `getBlockStandingOn()` - 获取站立的方块 通常来说,极度精确的检测是不太可能的。常规的标准方案是利用**多层级置信度累积模型**(AI时代这个东西已经很常见了吧),从即时触发到长期行为分析,分级处理: 首先呢,可以对一些白名单进行剔除(这个白名单是AI生成的): | 条件 | API | 逻辑 | |------|-----|------| | 创造/旁观模式 | `player.getGameMode()` | 返回 `creative` 或 `spectator` → 跳过 | | 鞘翅滑翔 | `player.isGliding` | `true` → 跳过(鞘翅有合法飞行) | | 缓降效果 | `player.getEffect('slow_falling')` | 存在 → 跳过 | | 浮漂状态 | `player.getEffect('levitation')` | 存在 → 跳过 | | 游泳中 | `player.isSwimming` / `player.isInWater` | 任一为 `true` → 跳过 | | 攀爬中 | `player.isClimbing` | `true` → 跳过 | | 骑乘中 | `player.hasComponent('minecraft:riding')` | `true` → 跳过 | | 近期传送 | 自定义标记(传送后给 3 秒冷却) | 传送后短时间内不计入检测 | 然后接下来就是采样(不知道为什么有股在做信技作业的感觉):每 tick(或每 N ticks)采样 `player.getVelocity()` + `player.location` 计算: ```typescript // 速度指标 const velocity = player.getVelocity(); const horizontalSpeed = Math.sqrt(velocity.x ** 2 + velocity.z ** 2); const verticalSpeed = velocity.y; // 位置差分(辅助验证) const prevLoc = lastLocationMap.get(player.id); // lastLocationMap具体逻辑不给出,这里只用做思维探究 const dt = 1; // 匀速采样时 const positionalSpeed = prevLoc ? Math.sqrt((loc.x-prevLoc.x)**2 + (loc.z-prevLoc.z)**2) / dt : 0; ``` 然后对于一些指标进行调控(当然还是AI生成的): | 指标 | 阈值 | 说明 | 严重度 | |------|------|------|--------| | 水平速度 > 12 m/s | `horizontalSpeed > 12` | 远超奔跑(5.6m/s)、疾跑(7.1m/s)最大值 | ⚡极高 | | 垂直速度 > 20 m/s | `verticalSpeed > 20` | 正常跳跃上升仅 ~0.42 m/s(初始速度) | ⚡极高 | | 水平速度 > 7.5 m/s 且 `!isOnGround` | 空中小飞侠 | 正常在空中无法加速到高速 | 🔴高 | | 水平速度 > 5.6 m/s 且 `isSprinting == false` | 非疾跑却高速 | 无法解释的速度来源 | 🔴高 | | 垂直上升速度 > 2 m/s 连续 3 ticks | 悬浮上升 | 正常跳跃上升会迅速衰减 | 🟡中 | | Y = 0 位置变化但 Y 速度 = 0 | 位置/速度不匹配 | 可能是注入/修改位置的作弊 | 🟡中 | ```typescript const onGround = player.isOnGround; const falling = player.isFalling; const blockBelow = player.getBlockStandingOn(); ``` | 模式 | 含义 | 响应 | |------|------|------| | `isOnGround == false` 但下方有固体方块且 Y 轴速度 ≈ 0 | 悬浮站立 | 🚩 标记 | | `isOnGround == true` 但 `getBlockStandingOn()` 返回 `undefined` | 浮空站 | 🚩 标记 | 然后再对于其他的各种行为进行标记,置信度判断,最后再拿结果。这种做法应该也很标准(人机识别、DDOS检测之类的,也差不多是这个玩意),想来应该是容易想到的,不太明白,为什么没人去写?(另外说一句,AI是真好用) [/MD]
 
解决方案
[MD] 呃,首先我不知道你是用哪种API,所以下面就用我最熟悉的基岩版SAPI为例: 对于玩家对象有以下的基础API: - `location: Vector3` - 当前位置 - `getVelocity(): Vector3` - 当前速度向量 - `isOnGround: boolean` - 是否在地面 - `isFalling: boolean` - 是否在下落 - `isClimbing: boolean` - 是否在攀爬 - `isInWater: boolean` - 是否在水中 - `isSwimming: boolean` - 是否在游泳 - `isGliding: boolean` - 是否用鞘翅滑翔 - `isFlying: boolean` - 是否在飞行(创造/旁观模式) - `isJumping: boolean` - 是否在跳跃 - `isSprinting: boolean` - 是否在冲刺 - `getGameMode(): GameMode` - 游戏模式 - `getBlockStandingOn()` - 获取站立的方块 通常来说,极度精确的检测是不太可能的。常规的标准方案是利用**多层级置信度累积模型**(AI时代这个东西已经很常见了吧),从即时触发到长期行为分析,分级处理: 首先呢,可以对一些白名单进行剔除(这个白名单是AI生成的): | 条件 | API | 逻辑 | |------|-----|------| | 创造/旁观模式 | `player.getGameMode()` | 返回 `creative` 或 `spectator` → 跳过 | | 鞘翅滑翔 | `player.isGliding` | `true` → 跳过(鞘翅有合法飞行) | | 缓降效果 | `player.getEffect('slow_falling')` | 存在 → 跳过 | | 浮漂状态 | `player.getEffect('levitation')` | 存在 → 跳过 | | 游泳中 | `player.isSwimming` / `player.isInWater` | 任一为 `true` → 跳过 | | 攀爬中 | `player.isClimbing` | `true` → 跳过 | | 骑乘中 | `player.hasComponent('minecraft:riding')` | `true` → 跳过 | | 近期传送 | 自定义标记(传送后给 3 秒冷却) | 传送后短时间内不计入检测 | 然后接下来就是采样(不知道为什么有股在做信技作业的感觉):每 tick(或每 N ticks)采样 `player.getVelocity()` + `player.location` 计算: ```typescript // 速度指标 const velocity = player.getVelocity(); const horizontalSpeed = Math.sqrt(velocity.x ** 2 + velocity.z ** 2); const verticalSpeed = velocity.y; // 位置差分(辅助验证) const prevLoc = lastLocationMap.get(player.id); // lastLocationMap具体逻辑不给出,这里只用做思维探究 const dt = 1; // 匀速采样时 const positionalSpeed = prevLoc ? Math.sqrt((loc.x-prevLoc.x)**2 + (loc.z-prevLoc.z)**2) / dt : 0; ``` 然后对于一些指标进行调控(当然还是AI生成的): | 指标 | 阈值 | 说明 | 严重度 | |------|------|------|--------| | 水平速度 > 12 m/s | `horizontalSpeed > 12` | 远超奔跑(5.6m/s)、疾跑(7.1m/s)最大值 | ⚡极高 | | 垂直速度 > 20 m/s | `verticalSpeed > 20` | 正常跳跃上升仅 ~0.42 m/s(初始速度) | ⚡极高 | | 水平速度 > 7.5 m/s 且 `!isOnGround` | 空中小飞侠 | 正常在空中无法加速到高速 | 🔴高 | | 水平速度 > 5.6 m/s 且 `isSprinting == false` | 非疾跑却高速 | 无法解释的速度来源 | 🔴高 | | 垂直上升速度 > 2 m/s 连续 3 ticks | 悬浮上升 | 正常跳跃上升会迅速衰减 | 🟡中 | | Y = 0 位置变化但 Y 速度 = 0 | 位置/速度不匹配 | 可能是注入/修改位置的作弊 | 🟡中 | ```typescript const onGround = player.isOnGround; const falling = player.isFalling; const blockBelow = player.getBlockStandingOn(); ``` | 模式 | 含义 | 响应 | |------|------|------| | `isOnGround == false` 但下方有固体方块且 Y 轴速度 ≈ 0 | 悬浮站立 | 🚩 标记 | | `isOnGround == true` 但 `getBlockStandingOn()` 返回 `undefined` | 浮空站 | 🚩 标记 | 然后再对于其他的各种行为进行标记,置信度判断,最后再拿结果。这种做法应该也很标准(人机识别、DDOS检测之类的,也差不多是这个玩意),想来应该是容易想到的,不太明白,为什么没人去写?(另外说一句,AI是真好用) [/MD]
woc感谢大佬!
 

在线会员

  • Ashsk
  • kilang
  • oYuyio
  • zerolin
后退
顶部 底部