Mineflayer.js机器人调用bot.chat()崩溃,报undefined的length属性错误
使用Mineflayer开发Minecraft机器人时bot.chat()抛出"Cannot read properties of undefined (reading 'length')"错误
问题描述
基于Mineflayer(依赖minecraft-protocol)开发1.19.2版本的MC机器人,调用bot.chat()时无论是否使用await都会触发序列化错误,错误核心提示为:TypeError: Serialization error for play.toServer : SizeOf error for undefined : Cannot read properties of undefined (reading 'length')。
代码示例
mineflayer = require('mineflayer'); let requirements = { 'host':'mc.ip.net', 'port':'88888', 'version':'1.19.2' }; class MCBot{ // Constructor constructor(username){ this.username = username; this.host = requirements['host']; this.port = requirements['port']; this.version = requirements['version']; this.initBot() }; // Init Bot Instance initBot(){ this.bot = mineflayer.createBot({ 'username': this.username, 'host': this.host, 'port': this.port, 'version': this.version }); this.initEvents() } // Init Bot Events initEvents(){ // Login Event this.bot.on('login', ()=>{ let botSocket = this.bot._client.socket; console.log(`[${this.username}] Logged in to ${botSocket.server ? botSocket.server : botSocket.host}`); }); // Disconnect Event this.bot.on('end', ()=>{ console.log(`[${this.username}] Disconnected`); // Reconnection Attempt setTimeout(()=> this.initBot, 2000); }); // Error Event this.bot.on('error', (err)=>{ if(err.code==='ECONNREFUSED'){ console.log(`[${this.username}] Failed to Reconnect to ${err.address}:${err.port}`); }else{ console.log(`[${this.username}] Unhandled Error: ${err}`); } }); // Spawn Event this.bot.on('spawn', async ()=>{ console.log(`[${this.username}] Spawned in`); await this.bot.waitForTicks(0) this.bot.chat(`${this.username}'s Ready!`); /* await this.bot.waitForTicks(60); this.bot.chat("Goodbye!"); this.bot.quit(); */ }); } } new MCBot("Bob") // let bots = ["Bob"] // for(var i = 0; i<bots.length; i++){ // bots.push(new MCBot(bots[i])) // console.log("Bot added") // }
错误日志
[Bob] Logged in to undefined [Bob] Spawned in TypeError: Serialization error for play.toServer : SizeOf error for undefined : Cannot read properties of undefined (reading 'length') at Object.previousMessages (eval at compile (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\compiler.js:258:12), <anonymous>:175:37) at Object.packet_chat_message (eval at compile (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\compiler.js:258:12), <anonymous>:599:37) at eval (eval at compile (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\compiler.js:258:12), <anonymous>:1222:64) at packet (eval at compile (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\compiler.js:258:12), <anonymous>:1270:9) at CompiledProtodef.sizeOf (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\compiler.js:89:14) at e.message (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\compiler.js:96:40) at tryCatch (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\utils.js:50:16) at CompiledProtodef.createPacketBuffer (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\compiler.js:96:20) at Serializer.createPacketBuffer (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\serializer.js:12:23) at Serializer._transform (C:\Users\xianc\Desktop\CHRIS\Minecraft\Bots\node_modules\protodef\src\serializer.js:18:18) { field: 'play.toServer' } [Bob] Unhandled Error: TypeError: Serialization error for play.toServer : SizeOf error for undefined : Cannot read properties of undefined (reading 'length') [Bob] Disconnected
解决方案
1. 修正端口数据类型
requirements中的port被定义为字符串类型,但Mineflayer的createBot方法要求port必须是数字类型。字符串端口会导致客户端底层初始化异常,进而引发聊天数据包序列化失败。
修改代码:
let requirements = { 'host':'mc.ip.net', 'port':88888, // 去掉引号,改为数字类型 'version':'1.19.2' };
2. 修复重连逻辑错误
在end事件的重连代码中,setTimeout(()=> this.initBot, 2000)仅传递了函数引用,并未实际调用初始化方法,导致断开后无法重新连接。需要改为:
setTimeout(()=> this.initBot(), 2000); // 加上()调用函数
3. 确保bot实例状态稳定
虽然spawn事件触发代表机器人已进入世界,但可以增加状态检查并延长等待时间,确保客户端完全初始化后再执行聊天操作:
this.bot.on('spawn', async ()=>{ console.log(`[${this.username}] Spawned in`); await this.bot.waitForTicks(20); // 等待更多ticks确保客户端稳定 if (this.bot._client && this.bot._client.state === 'play') { this.bot.chat(`${this.username}'s Ready!`); } });
修改后的完整代码
mineflayer = require('mineflayer'); let requirements = { 'host':'mc.ip.net', 'port':88888, // 改为数字类型 'version':'1.19.2' }; class MCBot{ constructor(username){ this.username = username; this.host = requirements['host']; this.port = requirements['port']; this.version = requirements['version']; this.initBot() }; initBot(){ this.bot = mineflayer.createBot({ 'username': this.username, 'host': this.host, 'port': this.port, 'version': this.version }); this.initEvents() } initEvents(){ this.bot.on('login', ()=>{ let botSocket = this.bot._client.socket; console.log(`[${this.username}] Logged in to ${botSocket.remoteAddress || botSocket.host}`); }); this.bot.on('end', ()=>{ console.log(`[${this.username}] Disconnected`); setTimeout(()=> this.initBot(), 2000); // 修复重连调用 }); this.bot.on('error', (err)=>{ if(err.code==='ECONNREFUSED'){ console.log(`[${this.username}] Failed to Reconnect to ${err.address}:${err.port}`); }else{ console.log(`[${this.username}] Unhandled Error: ${err}`); } }); this.bot.on('spawn', async ()=>{ console.log(`[${this.username}] Spawned in`); await this.bot.waitForTicks(20); if (this.bot._client && this.bot._client.state === 'play') { this.bot.chat(`${this.username}'s Ready!`); } }); } } new MCBot("Bob")
内容的提问来源于stack exchange,提问作者Christian Cangelli
相关产品推荐
相关产品推荐

