You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()
            })
        })
    }
}

问题根源

  1. 核心数据初始化时机错误:mcData和defaultMove在spawn事件前就初始化,此时bot.version未完全就绪,导致方块ID匹配、路径规划数据异常。
  2. 无非法输入校验:若输入的方块名不存在,mcData.blocksByName[bloccoDaTrovare].id会直接抛出undefined访问错误;数量参数是字符串,直接用于循环会导致逻辑异常。
  3. 事件绑定与异步逻辑混乱:用bot.on('goal_reached')而非once,可能导致多次触发;waitForTicks未异步等待,导致dig在看向方块前执行。
  4. 无错误捕获: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:15:02