你的第一個機器人
本頁將一個 bedboo 機器人連接到你自己運行的基岩版專用服務器(BDS)。如果你以前寫過 mineflayer 機器人,那麼只有前三步是新內容: 機器人代碼與 mineflayer 的寫法完全相同。
環境要求
- Node.js 24 或更高版本。RakNet 後端(raknet-native)只提供 x64 預編譯包(Linux、Windows、Intel 版 macOS); NetherNet 是純 JavaScript 實現,能運行 Node 的地方都能用。
- BDS 1.26.51.x(或 1.26.52.x,使用相同的 protocol 2193)。其他版本會在登錄時被拒絕。
獲取代碼
bedboo 尚未發佈到 npm。它對依賴(bedrock-protocol、nethernet、raknet-native、prismarine-*)的幾處小修復是 pnpm 補丁, 只在它的工作區內生效,因此請在 monorepo 中使用它:
git clone https://github.com/LiteLDev/bedboo
cd bedboo
corepack enable # pnpm 版本在 package.json 中固定(packageManager)
pnpm install把你的機器人放在一個工作區包中,讓它擁有自己的依賴(包括插件):
mkdir -p packages/my-bot
cat > packages/my-bot/package.json <<'EOF'
{
"name": "my-bot",
"private": true,
"dependencies": {
"bedboo": "workspace:*",
"mineflayer-pathfinder": "2.4.5"
}
}
EOF
pnpm install如果要把 bedboo 引入另一個 pnpm 項目,請複製 patches/、pnpm-workspace.yaml 中的 overrides、packageExtensions 和
patchedDependencies,以及 bedboo 和 bedrock-data 兩個包。沒有打過補丁的依賴,機器人無法加入服務器。
準備服務器
從 minecraft.net 安裝 BDS 1.26.51.x,並在
server.properties 中設置:
# 机器人默认通过 RakNet 加入(BDS 1.26.51 默认使用 nethernet;见下文“传输层”)
transport=raknet
# 离线机器人(auth: 'offline')没有 Xbox Live 身份
online-mode=false
# 或者保持为 true,并把机器人的名字加入 allowlist.json
allow-list=false
server-port=19132
# 可选:允许机器人执行命令(bot.chat('/time set day'))
allow-cheats=true| 屬性 | 值 | 原因 |
|---|---|---|
transport | raknet,或在 createBot 中使用 transport: 'nethernet' 時為 nethernet | RakNet 是客戶端的默認傳輸層 |
online-mode | auth: 'offline' 時為 false;true 需要 auth: 'microsoft' | 離線機器人沒有 Xbox Live 身份 |
allow-list | false,或把機器人的名字加入 allowlist.json | 否則機器人會被踢出 |
server-port | 傳給 createBot 的 port |
online-mode=false 允許任何人以任意名字加入:請把這樣的服務器放在私有網絡中,或者使用 online-mode=true 配合
Microsoft 賬號。在 transport=raknet 且 enable-lan-visibility=true 時,BDS 還會額外綁定
19132/19133 端口;在同一臺主機上運行多個服務器時請關閉它。
啟動服務器,等待日誌中出現 Server started.。緊隨其後的 TRANSPORT TYPE ERROR … not set to NetherNet 信息塊是 BDS
在提示原版客戶端可能很快需要 NetherNet;RakNet 客戶端可以正常連接。
編寫機器人
packages/my-bot/index.js 的寫法與 mineflayer 完全相同:
const bedboo = require('bedboo') // 替代 require('mineflayer')
const { pathfinder, Movements, goals } = require('mineflayer-pathfinder')
const bot = bedboo.createBot({
host: process.argv[2] ?? '127.0.0.1',
port: parseInt(process.argv[3] ?? '19132'),
username: 'Bot',
auth: 'offline'
})
bot.loadPlugin(pathfinder)
bot.once('spawn', () => {
console.log(`spawned at ${bot.entity.position} in ${bot.game.dimension} (${bot.game.gameMode})`)
bot.chat('hello!')
})
bot.on('chat', async (username, message) => {
if (username === bot.username) return
if (message === 'come') {
const target = bot.players[username]?.entity
if (!target) return bot.chat("I can't see you")
bot.pathfinder.setMovements(new Movements(bot))
try {
await bot.pathfinder.goto(new goals.GoalNear(target.position.x, target.position.y, target.position.z, 1))
bot.chat('here!')
} catch (err) {
bot.chat(`I can't get there: ${err.message}`) // 没有路径,或者新的 "come" 改变了目标
}
} else if (message === 'inventory') {
bot.chat(bot.inventory.items().map((item) => `${item.count} ${item.name}`).join(', ') || 'empty')
} else {
bot.chat(message)
}
})
bot.on('kicked', (reason) => console.log('kicked:', reason))
bot.on('error', (err) => console.log('error:', err))
bot.on('end', (reason) => console.log('disconnected:', reason))名稱使用基岩版的:bot.registry 是基岩版 1.26.51 的註冊表(grass_block、oak_log、stone_bricks……),因此
bot.registry.blocksByName.oak_log 和 bot.inventory.items()[0].name 得到的都是基岩版名稱。其餘一切(事件、
bot.dig、bot.placeBlock、bot.craft、窗口、bot.attack、物理)都是 mineflayer 的 API。不同之處列在
基岩版差異中。
運行
node packages/my-bot/index.js 127.0.0.1 19132用基岩版客戶端(或另一個機器人)加入服務器,在聊天中說 come,機器人就會走到你身邊。同一個文件改用 require('mineflayer')
後也能連接 Java 版服務器,只是基岩版方塊名稱不適用。
庫的 examples/ 目錄收錄了移植到基岩版的 mineflayer 示例(node examples/<name>.js <host> <port> [<name>]),
放在其中的腳本無需任何配置即可解析到本庫和 mineflayer-pathfinder。
權限、作弊與命令
bot.chat('/…')發送的是命令請求(基岩版沒有通過聊天輸入的命令)。命令需要allow-cheats=true和管理員權限:在 BDS 上 玩家無法給自己 op,因此請在服務器控制台中給機器人 op(op Bot),或者設置default-player-permission-level=operator。- 命令結果以
message事件的形式到達(基岩版的command_output,每行一個)。 /give、/replaceitem、/tp等命令的效果對機器人可見,與 Java 版一致(playerCollect、forcedMove……)。
Microsoft(Xbox Live)賬號
對於 online-mode=true 的服務器,請使用擁有 Minecraft 的 Microsoft 賬號:
const bot = bedboo.createBot({
host: 'my.server.example',
port: 19132,
username: 'me@example.com', // 令牌缓存使用的名字
auth: 'microsoft',
profilesFolder: './.auth-cache' // 可选;选项与 mineflayer 相同(prismarine-auth)
})首次運行會打印一個設備碼鏈接(可以用 onMsaCode 自行處理);之後令牌會被緩存。遊戲內名稱為該賬號的玩家代號(gamertag)。
auth: 'mojang' 在基岩版上不存在,會拋出錯誤。
傳輸層:RakNet 或 NetherNet
BDS 1.26.51 默認使用 NetherNet(WebRTC 數據通道),RakNet 需通過 transport=raknet 啟用。Mojang 已表示將移除
RakNet,最早可能在 BDS 26.60。除非另行指定,bedboo 都通過 RakNet 連接,因為 bedrock-protocol 支持它已有多年。要使用
NetherNet,請以 transport=nethernet 啟動 BDS,並將傳輸層傳給 createBot:
const bot = bedboo.createBot({ host: '127.0.0.1', port: 19132, username: 'Bot', transport: 'nethernet' })- 信令走的是服務器端口上的 HTTP(
POST http://<host>:<port>/v1/join/<id>),因此在enable-lan-visibility=false時也能工作,也可以通過轉發server-port(TCP)端口使用;之後的媒體流走 UDP(BDS 的server-udp-ports)。 bedrock-protocol 的其他信令模式也會透傳,但測試較少:局域網發現(UDP 7551,需要enable-lan-visibility=true),使用nethernet: { signalling: 'lan' };以及 Xbox 信令,使用nethernet: { signalling: 'services', networkId }+auth: 'microsoft'。 - 服務器密鑰。 BDS 會用一個身份密鑰對應答進行簽名。在明文 HTTP 上沒有任何機制為該密鑰背書,因此默認接受任意密鑰,
這與 RakNet 提供的信任程度相同。可以固定密鑰以拒絕冒充者:
nethernet: { serverKey: 'sha256:<hex>' };nethernet: { onServerKey: (fingerprint, url) => true | false }讓你自行決定(並展示可用於固定的指紋)。HTTPS 信令 URL(nethernet: { url: 'https://…' })通過 TLS 獲得信任。 - 機器人的 API 在兩種傳輸層上完全相同。詳情:連接與版本。
故障排查
| 現象 | 原因 |
|---|---|
Connect timed out | 主機或端口錯誤、服務器的 transport 與機器人不一致,或防火牆丟棄了 UDP(RakNet)/ TCP(NetherNet 信令) |
登錄後立即 kicked | allow-list=true 但機器人不在 allowlist.json 中,或 online-mode=true 卻使用 auth: 'offline'(reason 會說明是哪一種) |
| 以客戶端 / 服務器版本過舊為由被踢出 | 服務器不是 1.26.51.x / 1.26.52.x |
| RakNet 後端加載失敗 | 不是 x64,或依賴是在工作區之外安裝的(缺少 raknet-native 補丁) |
| 命令被拒絕 | 在控制台給機器人 op,並開啟作弊(allow-cheats=true) |
NetherNet:Untrusted Nethernet server key | serverKey 固定值與服務器的密鑰不匹配(或 onServerKey 返回了 false) |
NetherNet:fetch failed(ECONNREFUSED) | 服務器運行的是 RakNet,或 BDS 無法打開 TCP 信令監聽(此時日誌中沒有 Accepting clients on … 一行;端口被其他進程佔用) |
更多值得了解的 BDS 行為(加入流程、區塊加載、控制台輸出)彙總在 BDS 筆記中。