RakNet & NetherNet 通信
gophertunnel は、Minecraft Bedrock Edition がトランスポート層で使用するネットワークプロトコルを minecraft.Network インターフェースとして抽象化しています。
サポートされるネットワークドライバ
Dialer.Dial(network, address) や ListenConfig.Listen(network, address) の第1引数に渡すプロトコル名として、以下が標準登録されています。
| ネットワーク名 | 実装 | 特徴・用途 |
|---|---|---|
"raknet" | github.com/sandertv/go-raknet | Bedrock の標準通信プロトコル(UDPベース)。サーバー待受や通常サーバーへの接続で使用。 |
"nethernet" | WebRTC ベースの P2P 通信 | 近年の Realms やフレンド間マルチプレイで採用されているプロトコル。 |
RakNet によるサーバー Ping (MOTD取得)
接続(Dial)する前に、サーバーがオンラインか、プレイヤーが何人いるかなどを高速にチェックしたい場合、minecraft.PingContext を使用します。
go
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/sandertv/gophertunnel/minecraft"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
// RakNet Pong データを取得
pongData, err := minecraft.PingContext(ctx, "play.inpvp.net:19132")
if err != nil {
log.Fatalf("Ping 失敗: %v", err)
}
// Pong データを構造体にパース
status, err := minecraft.ParsePong(pongData)
if err != nil {
log.Fatalf("Pong パース失敗: %v", err)
}
fmt.Printf("=== サーバー情報 ===\n")
fmt.Printf("MOTD: %s\n", status.ServerName)
fmt.Printf("サブMOTD: %s\n", status.SubServerName)
fmt.Printf("バージョン: %s (プロトコル %d)\n", status.Version, status.ProtocolVersion)
fmt.Printf("プレイヤー数: %d / %d\n", status.PlayerCount, status.MaxPlayers)
fmt.Printf("ゲームモード: %s\n", status.GameType)
}独自トランスポートの拡張 (RegisterNetwork)
gophertunnel では、独自のネットワーク層(例えば TCP トンネル、WebSocket、特殊な暗号化トランスポート)を minecraft.RegisterNetwork で追加登録することが可能です。
go
func init() {
minecraft.RegisterNetwork("custom_udp", func(l *slog.Logger) minecraft.Network {
return &MyCustomNetwork{logger: l}
})
}これによって、dialer.Dial("custom_udp", "...") で透過的に独自の通信路を利用できるようになります。