Mineflayer机器人执行Blocchi函数时未挖掘即崩溃
Mineflayer机器人挖掘方块前崩溃问题修复
问题描述
通过聊天指令执行trova [方块名] [数量]调用Blocchi函数时,机器人在开始挖掘前就崩溃,控制台提示“unknown reasons”。调整maxDistance参数后问题仍未解决,预期机器人能在指定范围内找到目标方块并挖掘对应数量。
原代码
const mineflayer = require('mineflayer') const pathfinder = require('mineflayer-pathfinder').pathfinder const Movements = require('mineflayer-pathfinder').Movements const { GoalNear } = require('mineflayer-pathfinder').goals const inventoryViewer = require('mineflayer-web-inventory') let options = { host: 'localhost', port: 50599, username: 'Specchiopaura', version: '1.19.2' } const bot = mineflayer.createBot(options) inventoryViewer(bot) bot.once('spawn', () => { console.log('-CONNESSO-') bot.loadPlugin(pathfinder) }) const mcData = require('minecraft-data')(bot.version) const defaultMove = new Movements(bot, mcData) bot.on('chat', (username, message) =>{ args = message.split(' ') if(args[0] == 'quitta'){bot.quit()} else if(args[0] == 'trova') { Blocchi(args[1], args[2]) } else if(args[0] == 'aprichest') { let chest = bot.findBlock({matching: mcData.blocksByName.chest.id, maxDistance: 64}) const goal = chest.position bot.pathfinder.setMovements(defaultMove) bot.pathfinder.setGoal(new GoalNear(chest.position.x, chest.position.y, chest.position.z, 1)) bot.once('goal_reached', () => { bot.lookAt(chest.position.offset(0.5, 0.5, 0.5)); bot.openChest(chest) }) } }) async function Blocchi(bloccoDaTrovare, contatore) { for (let i = 0; i < contatore; i++) { let block = bot.findBlock({ matching: mcData.blocksByName[bloccoDaTrovare].id, maxDistance: 10 }) console.log(block.position) if (!block) { return } await bot.pathfinder.setMovements(defaultMove) await bot.pathfinder.setGoal(new GoalNear(block.position.x, block.position.y, block.position.z, 1)) await new Promise(resolve => { bot.on('goal_reached', () => { bot.lookAt(block.position.offset(0.5, 0.5, 0.5)) bot.waitForTicks(10) bot.dig(block) resolve() }) }) } }
问题根源
- 核心数据初始化时机错误:
mcData和defaultMove在spawn事件前就初始化,此时bot.version未完全就绪,导致方块ID匹配、路径规划数据异常。 - 无非法输入校验:若输入的方块名不存在,
mcData.blocksByName[bloccoDaTrovare].id会直接抛出undefined访问错误;数量参数是字符串,直接用于循环会导致逻辑异常。 - 事件绑定与异步逻辑混乱:用
bot.on('goal_reached')而非once,可能导致多次触发;waitForTicks未异步等待,导致dig在看向方块前执行。 - 无错误捕获:
dig操作抛出的异常未被捕获,直接导致机器人崩溃。
修复后的代码
const mineflayer = require('mineflayer') const pathfinder = require('mineflayer-pathfinder').pathfinder const Movements = require('mineflayer-pathfinder').Movements const { GoalNear } = require('mineflayer-pathfinder').goals const inventoryViewer = require('mineflayer-web-inventory') let options = { host: 'localhost', port: 50599, username: 'Specchiopaura', version: '1.19.2' } const bot = mineflayer.createBot(options) inventoryViewer(bot) let mcData, defaultMove bot.once('spawn', () => { console.log('-CONNESSO-') bot.loadPlugin(pathfinder) // 确保bot版本就绪后再初始化核心数据 mcData = require('minecraft-data')(bot.version) defaultMove = new Movements(bot, mcData) }) bot.on('chat', (username, message) =>{ const args = message.split(' ') if(args[0] === 'quitta'){ bot.quit() return } if(args[0] === 'trova'){ // 校验参数完整性 if(!args[1] || !args[2]){ bot.chat('用法:trova [方块名] [数量]') return } const blockName = args[1] const count = parseInt(args[2]) // 校验数量合法性 if(isNaN(count) || count <= 0){ bot.chat('数量必须是正整数') return } Blocchi(blockName, count) return } if(args[0] === 'aprichest'){ const chest = bot.findBlock({matching: mcData.blocksByName.chest.id, maxDistance: 64}) if(!chest){ bot.chat('附近没有箱子') return } bot.pathfinder.setMovements(defaultMove) bot.pathfinder.setGoal(new GoalNear(chest.position.x, chest.position.y, chest.position.z, 1)) bot.once('goal_reached', () => { bot.lookAt(chest.position.offset(0.5, 0.5, 0.5)) bot.openChest(chest) }) } }) async function Blocchi(blockName, count) { // 校验方块名称是否存在 const blockInfo = mcData.blocksByName[blockName] if(!blockInfo){ bot.chat(`不存在名为${blockName}的方块`) return } const blockId = blockInfo.id for (let i = 0; i < count; i++) { // 每次循环重新查找方块,适配挖完后的场景 const block = bot.findBlock({ matching: blockId, maxDistance: 10 }) if (!block) { bot.chat(`找不到更多${blockName}方块,停止挖掘`) return } bot.pathfinder.setMovements(defaultMove) bot.pathfinder.setGoal(new GoalNear(block.position.x, block.position.y, block.position.z, 1)) // 用once确保仅触发一次到达目标事件 await new Promise(resolve => { bot.once('goal_reached', resolve) }) // 异步等待看向方块完成 bot.lookAt(block.position.offset(0.5, 0.5, 0.5)) await bot.waitForTicks(10) // 捕获挖掘错误,避免机器人崩溃 try { await bot.dig(block) console.log(`已挖掘第${i+1}个${blockName}`) } catch (err) { console.error(`挖掘失败: ${err.message}`) bot.chat(`挖掘第${i+1}个${blockName}失败: ${err.message}`) } } bot.chat(`已完成挖掘${count}个${blockName}`) }
修复说明
- 延迟核心数据初始化:将
mcData和defaultMove移到spawn事件中,确保bot.version有效,避免数据异常。 - 完善参数校验:检查方块名是否存在、数量是否为正整数,拦截非法输入。
- 优化循环逻辑:每次循环重新查找方块,确保挖完一个后能定位到下一个目标。
- 修正异步与事件绑定:用
once绑定goal_reached事件,避免重复触发;异步等待waitForTicks,确保看向方块后再执行挖掘。 - 增加错误捕获:给
dig操作添加try/catch,捕获并输出错误,防止机器人崩溃。
内容的提问来源于stack exchange,提问作者KxAy
相关产品推荐
相关产品推荐

