圧縮・暗号化・フラッシュ
Bedrock Edition の通信では、高頻度に送受信されるパケットを効率的に送るために、バッファリング(FlushRate)、一括圧縮、ストリーム暗号化 がパイプラインとして組み合わされています。
処理のパイプライン
conn.WritePacket() を呼んだとき、データは以下のような流れで送信されます。
圧縮アルゴリズム (Compression)
Bedrock では主に以下の圧縮方式がサポートされています。
| 方式 | 識別子 (uint16) | 特徴・デフォルト設定 |
|---|---|---|
FlateCompression | 0 (Zlib/Deflate) | gophertunnelのデフォルト。CPU効率と圧縮率のバランスが良く、安定している。 |
SnappyCompression | 1 (Snappy) | 高速圧縮。Minecraft公式でも採用されているが、一部の非AVX2環境等での互換性に注意。 |
NopCompression | - | 圧縮を行わない(デバッグやベンチマーク用)。 |
サーバーでの圧縮設定
go
lc := minecraft.ListenConfig{
// 圧縮アルゴリズムの指定
Compression: packet.SnappyCompression,
// 圧縮を適用する閾値(バイト単位)
// デフォルトは 256 バイト。これ以下の小さなパケットは非圧縮で送られる
// -1 に設定すると圧縮を完全にオフにできる
CompressionThreshold: 512,
}パケットのフラッシュレート (FlushRate)
Minecraft では、複数のパケットを1つのバッファにまとめて圧縮・暗号化することで、パケットごとのオーバーヘッドを削減します。
- デフォルトの
FlushRateはtime.Second / 20(50ms = 1ゲームTick)。 - 50msごとに溜まったパケットが一括送信されます。
低レイテンシ化・即時送信
リアルタイム性が求められるプロキシやボットでは、パケットを即座に届けたい場合があります。
go
// 1. ListenConfig で FlushRate を短くする (例: 10ms)
lc := minecraft.ListenConfig{
FlushRate: 10 * time.Millisecond,
}
// 2. 自動フラッシュを無効化し、手動で Flush() を呼ぶ
lc := minecraft.ListenConfig{
FlushRate: -1, // 自動フラッシュ停止
}
// 送信側
_ = conn.WritePacket(pk)
_ = conn.Flush() // 即座にネットワークへ押し出すパケット暗号化 (AES-CFB8 & ECDH)
Minecraft Bedrock では、ハンドシェイク時にクライアントとサーバーが ECDH(楕円曲線ディフィー・ヘルマン鍵交換)を行い、共通鍵を導出して AES-CFB8 でパケットストリームを暗号化します。
- 自動管理:
DialerやListenerを使用する場合、暗号化ハンドシェイクは完全に自動で行われます。 - 暗号化の無効化: LAN内専用サーバーや自作クライアント同士でのパケット解析を行う場合、
ListenConfig.DisablePacketEncryption = trueにすることで暗号化をスキップできます(※公式クライアントが接続する場合は暗号化が必要になります)。