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

Mineflayer Bot挖掘时触发聊天指令超时崩溃问题及中断方案咨询

Mineflayer Bot挖掘超时错误分析及中断方案

问题背景

运行以下Python代码控制Mineflayer Bot时,若Bot处于挖掘状态发送聊天消息,会触发BridgeException超时错误,同时需要实现通过聊天指令中断挖掘循环的功能。

相关代码

from javascript import require, On, Once, AsyncTask, once, off

mineflayer = require('mineflayer')
inventoryViewer = require('mineflayer-web-inventory')
item = require('prismarine-item')


# 创建Bot
BOT_USERNAME = 'Robol'
bot = mineflayer.createBot({
    'host': 'localhost',
    'port': 55337,
    'username': BOT_USERNAME,
    'hideErrors': False,
    'version': '1.18.1'})

inventoryViewer(bot)


@On(bot, 'chat')
def handle(this, sender, message, *args):
    if sender == BOT_USERNAME:
        return

    msg = message.split()

    if message.startswith('.stop'):
        bot.end()
    if message.startswith('.tph'):
        teleport(sender)
    if message.startswith('.dig'):
        dig_down()
    if message.startswith('.drop'):
        if len(msg) > 1:
            drop(msg[1])
        else:
            drop(1)


def blockUnder(playerName):
    if playerName == BOT_USERNAME:
        return bot.blockAt(bot.entity.position.offset(0, -1, 0))
    else:
        return bot.blockAt(bot.players[playerName].entity.position.offset(0, -1, 0))


def teleport(playerName):
    if playerName in bot.players:
        if blockUnder(playerName).displayName == 'Air':
            bot.chat('You have to stand on the ground')
        else:
            bot.chat(f'/tp {playerName}')
    else:
        bot.chat('No entity was found')


def dig_down():
    try:
        while bot.canDigBlock(blockUnder(BOT_USERNAME)):
            bot.dig(blockUnder(BOT_USERNAME))

        bot.chat("Can't dig deeper")
    except Exception:
        bot.chat("Stopped digging")

报错信息

[JSE] C:\Users\BigGay\PycharmProjects\BOT\venv\lib\site-packages\javascript\js\pyi.js:149
[JSE]       throw new BridgeException(`Attempt to access '${stack.join('.')}' failed.`)
[JSE]             ^
[JSE] 
[JSE] BridgeException [Error]: Attempt to access '' failed. Python didn't respond in time (100000ms), look above for any Python errors. If no errors, the API call hung.
[JSE]     at C:\Users\BigGay\PycharmProjects\BOT\venv\lib\site-packages\javascript\js\pyi.js:149:13
[JSE]     at waitFor (C:\Users\BigGay\PycharmProjects\BOT\venv\lib\site-packages\javascript\js\pyi.js:46:26)
[JSE]     at async PyBridge.call (C:\Users\BigGay\PycharmProjects\BOT\venv\lib\site-packages\javascript\js\pyi.js:148:18)
[JSE] 
[JSE] Node.js v18.12.1

Process finished with exit code 0

核心问题

  1. 该超时错误的产生原因是什么?
  2. 如何通过聊天指令中断dig_down()中的挖掘循环?

问题原因

dig_down()里的同步while循环直接阻塞了Python主线程:bot.dig()是异步操作,但你用同步循环反复调用它,导致主线程完全卡在挖掘逻辑里,根本没时间响应Node.js推送的聊天事件。当你在挖掘时发消息,Node.js尝试调用Python的聊天处理函数,但Python主线程被循环卡死,无法及时处理请求,超时后就触发了BridgeException。

解决方案

1. 修复超时错误

将同步阻塞的循环改成异步非阻塞写法,让主线程能腾出时间处理其他事件(比如聊天)。

2. 实现聊天中断挖掘

添加全局中断标志,在聊天指令中修改标志状态,同时在异步挖掘循环中检查该标志,一旦触发就停止挖掘。

修改后的完整代码:

from javascript import require, On, Once, AsyncTask, once, off, await_

mineflayer = require('mineflayer')
inventoryViewer = require('mineflayer-web-inventory')
item = require('prismarine-item')


# 创建Bot
BOT_USERNAME = 'Robol'
bot = mineflayer.createBot({
    'host': 'localhost',
    'port': 55337,
    'username': BOT_USERNAME,
    'hideErrors': False,
    'version': '1.18.1'})

inventoryViewer(bot)

# 挖掘中断标志
stop_digging = False

@On(bot, 'chat')
def handle(this, sender, message, *args):
    global stop_digging
    if sender == BOT_USERNAME:
        return

    msg = message.split()

    if message.startswith('.stop'):
        bot.end()
    elif message.startswith('.tph'):
        teleport(sender)
    elif message.startswith('.dig'):
        stop_digging = False
        # 用AsyncTask包装异步函数,避免阻塞主线程
        AsyncTask(dig_down)()
    elif message.startswith('.digstop'):
        stop_digging = True
        bot.chat('Stopping dig...')
    elif message.startswith('.drop'):
        if len(msg) > 1:
            drop(msg[1])
        else:
            drop(1)


def blockUnder(playerName):
    if playerName == BOT_USERNAME:
        return bot.blockAt(bot.entity.position.offset(0, -1, 0))
    else:
        return bot.blockAt(bot.players[playerName].entity.position.offset(0, -1, 0))


def teleport(playerName):
    if playerName in bot.players:
        if blockUnder(playerName).displayName == 'Air':
            bot.chat('You have to stand on the ground')
        else:
            bot.chat(f'/tp {playerName}')
    else:
        bot.chat('No entity was found')


async def dig_down():
    global stop_digging
    try:
        # 循环同时检查中断标志和可挖掘状态
        while not stop_digging and bot.canDigBlock(blockUnder(BOT_USERNAME)):
            # await等待挖掘完成,避免循环过快占用资源
            await_(bot.dig(blockUnder(BOT_USERNAME)))
        
        if stop_digging:
            bot.chat('Digging stopped by command')
        else:
            bot.chat("Can't dig deeper")
    except Exception as e:
        bot.chat(f"Digging stopped with error: {str(e)}")

修改说明

  • 新增stop_digging全局变量作为中断开关,发送.digstop指令即可触发中断。
  • dig_down改为异步函数,用await_等待bot.dig()完成,避免无效循环阻塞线程。
  • 用AsyncTask包装dig_down调用,让挖掘逻辑在后台异步执行,不占用主线程,聊天事件能正常响应。
  • 循环条件加入not stop_digging,每次循环都会检查是否需要中断。

内容的提问来源于stack exchange,提问作者Kasperro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 13:35:26