Skip to content

エコシステムとの連携

bedrock-protocol は単体では「パケットの送受信」までを担います。ここではリポジトリの examples や依存関係から読み取れる、PrismarineJS エコシステムとの組み合わせを紹介します。

実ワールドの配信(bedrock-provider)

examples/server/serverChunks.js では、Bedrock Edition の実データ(LevelDB)を読み込んでチャンクを配信しています。

js
const { WorldProvider } = require('bedrock-provider')
const { LevelDB } = require('leveldb-zlib')
const { join } = require('path')

async function loadWorld(version) {
  // BDS のワールドディレクトリにある db を直接読む
  const db = new LevelDB(join(__dirname, 'worlds/Bedrock level/db'), { createIfMissing: false })
  await db.open()
  const wp = new WorldProvider(db, { dimension: 0 })

  async function requestChunks(x, z, radius) {
    const chunks = []
    for (let cx = (x >> 4) - radius; cx < (x >> 4) + radius; cx++) {
      for (let cz = (z >> 4) - radius; cz < (z >> 4) + radius; cz++) {
        const cc = await wp.load(cx, cz, true)
        if (!cc) continue
        chunks.push({
          x: cx,
          z: cz,
          sub_chunk_count: cc.sectionsLen,
          cache_enabled: false,
          blobs: [],
          payload: await cc.networkEncodeNoCache()
        })
      }
    }
    return chunks // level_chunk パラメータとしてそのまま queue() できる
  }

  return { requestChunks }
}

リソースパックフローのハンドリング

クライアント側は resource_packs_inforesource_pack_client_responseresource_pack_stack の応答チェーンを自分で処理できます。カスタムリソースパック対応サーバーを作るときの最小形(examples/client/clientInternal.js 抜粋):

js
client.once('resource_packs_info', packet => {
  client.write('resource_pack_client_response', {
    response_status: 'completed',
    response_status_name: 'resourcepackstackfinished',
    resourcepackids: []
  })

  client.once('resource_pack_stack', stack => {
    client.write('resource_pack_client_response', {
      response_status: 'completed',
      response_status_name: 'resourcepackstackfinished',
      resourcepackids: []
    })
  })
})

autoInitPlayer との関係

この手のフローを完全手動にする場合は autoInitPlayer: false にして、初期化パケット送信後に自前で client.status = ClientStatus.Initialized(=4)を設定します。デフォルトでは 'spawn' イベントが発火しなくなる点に注意してください(実装は src/options.js のコメント参照)。

認証タイトル(Titles)と DeviceOS

src/client/auth.js より。authTitle 未指定時の 既定値は Nintendo Switch です。BDS はログイン内の DeviceOS と認証プラットフォームの整合性を検証するため、カスタムタイトルを使う場合は deviceOS の指定が必須になります。

js
const { title: Titles } = require('bedrock-protocol') // prismarine-auth の Titles

Titles.MinecraftNintendoSwitch // 既定
Titles.MinecraftAndroid
Titles.MinecraftIOS
Titles.MinecraftPlaystation
authTitle対応する DeviceOS 値
MinecraftAndroid1
MinecraftIOS2
MinecraftPlaystation11
MinecraftNintendoSwitch12

上記以外の authTitle には deviceOS オプション(数値)が必須です。

バニラサーバーを使ったテスト環境

リポジトリの npm スクリプトとツール:

bash
# bedrock-protocol リポジトリ内で
npm run vanillaServer   # minecraft-bedrock-server で実物 BDS を起動
npm run dumpPackets     # 実パケットダンプを生成(tools/genPacketDumps.js)
npm test                # 実際に BDS に対して全バージョンでテスト

test/vanilla.js には 本物の BDS と最後までスポーンシーケンスを完走する 参考実装があるため、独自サーバー実装時の仕様確認に有用です。

プロトコルデータの供給源

すべてのパケット定義は minecraft-data(bedrock_<version>)から来ており、mcData.supportFeature() による機能フラグ判定(compressorInPacketHeadernewLoginIdentityFields など)も内部で使われています。バージョン分岐を実装するときは versionLessThan() 系メソッドかこの feature フラグを使うのが確実です。