fix: 修复登录按钮死锁,移植旧版 player_input 补包解决「机器人走不动」
控制台登录按钮点不动(致命) - bindEvents() 只在 startApp() 里执行,而 startApp() 只在登录成功后才跑, 未登录时登录按钮根本没绑上事件,形成死锁。现在在 main() 里无条件绑定。 机器人走不动(致命,根因定位并修复) - mineflayer 不发 player_input 包:1.21.2+ 服务端的移动预测依赖它,原版客户端每 tick 都发, 而 mineflayer 只在骑乘/跳下/潜行时发,地面移动的 forward/jump/sprint 完全不发。 带反作弊的服务器判定「没有任何输入却发生位移」,每 tick 把玩家拉回原位置。 实测:修复前入站强制位置同步约 17 次/秒、按方向键 2 秒位移 0.00 格; 修复后入站降到 0 次、位移 0.53~1.40 格。该修复来自旧版机器人(感谢原作者)。 - 同时补发 tick_end(原版每 tick 末尾发送,反作弊用它判定 tick 边界,mineflayer 完全不发) - 资源包未自动接受会卡在加载界面进不了世界,现自动接受 - configure() 每次配置变更都重复注册寻路事件监听,导致同一事件被处理多次 长距离分段寻路 - mineflayer-pathfinder 只能规划已加载区块范围(实测约 8 区块 ≈ 130 格), 扩地目标常在几十个区块外,A* 瞬间 noPath。现在自动拆段:走到已加载范围边缘 → 新区块加载 → 再规划。 段长用 bot.blockAt 对未加载区块返回 null 的特性二分探测,不依赖世界内部结构。 新增 - pathing.thinkTimeoutMs / tickTimeoutMs / searchRadius(负值表示不限制剪枝) - 位置包收发计数、player_input/tick_end 计数、游戏模式、维度、脚下方块、 六向「脚部/头部/地面」与可通行判定等诊断字段 - 手动移动测试按钮(绕开寻路器直接按方向键并回报真实位移) 已知限制 - 机器人当前所在位置 (6759,72,11926) 无法寻路:A* 恒定只展开 47 个节点就 noPath。 已逐项排除挖方块/放方块/跑酷/搭塔/开门/最大下落(试到 64 格)/高度偏好/水域代价/ 搜索半径(试到不限制)/时间预算/依赖版本(与能正常移动的旧机器人完全一致)。 旧机器人日志证明寻路可用(2 次 goal_reached、2 秒走 8.7 格),但它当时在 y=-59, 本机器人被 /spawn 放到了 y=72。下一步需把机器人挪到开阔地再试。 测试 290 -> 308,全部通过。
这个提交包含在:
+23
-2
@@ -180,7 +180,9 @@ const CONFIG_SCHEMA = {
|
||||
{ path: 'pathing.allow1by1towers', label: '允许 1×1 搭塔', type: 'checkbox' },
|
||||
{ path: 'pathing.maxDropDown', label: '最大下落高度(格)', type: 'number', min: 0 },
|
||||
{ path: 'pathing.liquidCost', label: '液体格额外代价', type: 'number', min: 1 },
|
||||
{ path: 'pathing.canOpenDoors', label: '允许开门', type: 'checkbox' }
|
||||
{ path: 'pathing.canOpenDoors', label: '允许开门', type: 'checkbox' },
|
||||
{ path: 'pathing.maxSegmentBlocks', label: '单段寻路最长距离(格)', type: 'number', min: 32, hint: '寻路器只能规划已加载区块范围(本服约 130 格),长距离会自动拆段;此项只是单段上限' },
|
||||
{ path: 'pathing.segmentMarginBlocks', label: '分段安全边距(格)', type: 'number', min: 0, hint: '分段时距已加载范围边缘留出的余量,避免踩在未加载边界上' }
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -260,7 +262,9 @@ const CONFIG_SCHEMA = {
|
||||
{ path: 'grim.blockConflictingActions', label: '拦截冲突动作组合', type: 'checkbox' },
|
||||
{ path: 'grim.checkPhysicsIntegrity', label: '启动物理参数自检', type: 'checkbox' },
|
||||
{ path: 'grim.blockActionsWhileRiding', label: '骑乘时禁止攻击 / 进食', type: 'checkbox' },
|
||||
{ path: 'grim.reportOnGroundFromWorld', label: '按世界数据修正 onGround', type: 'checkbox', hint: '服务端频繁下发位置包时,mineflayer 会持续上报「站地上却在空中」而被反作弊每 tick 拉回;开启后在发包前用脚下方块复核(实测本服必需)' }
|
||||
{ path: 'grim.reportOnGroundFromWorld', label: '按世界数据修正 onGround', type: 'checkbox', hint: '服务端频繁下发位置包时,mineflayer 会持续上报「站地上却在空中」而被反作弊每 tick 拉回;开启后在发包前用脚下方块复核(实测本服必需)' },
|
||||
{ path: 'grim.sendPlayerInput', label: '每 tick 补发 player_input', type: 'checkbox', hint: '1.21.2+ 移动预测依赖它;mineflayer 地面移动时完全不发,导致反作弊判定「无输入却位移」并把机器人每 tick 拉回(实测本服必需)' },
|
||||
{ path: 'grim.sendTickEnd', label: '每 tick 补发 tick_end', type: 'checkbox', hint: '原版 1.21.2+ 客户端每 tick 末尾发送,反作弊用它判定 tick 边界' }
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -1474,6 +1478,21 @@ function connectWs() {
|
||||
|
||||
// ==================== 事件绑定 ====================
|
||||
|
||||
/**
|
||||
* 绑定登录相关的按钮。
|
||||
*
|
||||
* 必须在 `main()` 里无条件调用:这些按钮要在「尚未登录」时就能用,
|
||||
* 而 `bindEvents()` 只在 `startApp()` 里执行,`startApp()` 又只在登录成功后才跑 ——
|
||||
* 把登录按钮放进去会形成死锁,表现就是「输入密码点登录没反应」。
|
||||
*/
|
||||
function bindAuthEvents() {
|
||||
$('btnLogin').addEventListener('click', doLogin);
|
||||
$('loginPassword').addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') doLogin();
|
||||
});
|
||||
$('btnLogout').addEventListener('click', doLogout);
|
||||
}
|
||||
|
||||
function bindEvents() {
|
||||
$('botSelect').addEventListener('change', () => selectBot($('botSelect').value));
|
||||
|
||||
@@ -1881,6 +1900,8 @@ async function startApp() {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// 登录按钮必须最先绑定:未登录时 startApp() 不会执行,绑在里面就点不动
|
||||
bindAuthEvents();
|
||||
const ok = await checkSession();
|
||||
if (ok) await startApp();
|
||||
else $('loginPassword').focus();
|
||||
|
||||
在新工单中引用
屏蔽一个用户