跳到正文
本頁目錄

你的第一個機器人

本頁將一個 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 中使用它:

sh
git clone https://github.com/LiteLDev/bedboo
cd bedboo
corepack enable   # pnpm 版本在 package.json 中固定(packageManager)
pnpm install

把你的機器人放在一個工作區包中,讓它擁有自己的依賴(包括插件):

sh
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 中設置:

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
屬性值原因
transportraknet,或在 createBot 中使用 transport: 'nethernet' 時為 nethernetRakNet 是客戶端的默認傳輸層
online-modeauth: 'offline' 時為 false;true 需要 auth: 'microsoft'離線機器人沒有 Xbox Live 身份
allow-listfalse,或把機器人的名字加入 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 完全相同:

js
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。不同之處列在 基岩版差異中。

運行

sh
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 賬號:

js
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:

js
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 信令)
登錄後立即 kickedallow-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 keyserverKey 固定值與服務器的密鑰不匹配(或 onServerKey 返回了 false)
NetherNet:fetch failed(ECONNREFUSED)服務器運行的是 RakNet,或 BDS 無法打開 TCP 信令監聽(此時日誌中沒有 Accepting clients on … 一行;端口被其他進程佔用)

更多值得了解的 BDS 行為(加入流程、區塊加載、控制台輸出)彙總在 BDS 筆記中。