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
核心问题
- 该超时错误的产生原因是什么?
- 如何通过聊天指令中断
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
相关产品推荐
相关产品推荐

