Skip to content

RakNet & NetherNet 通信

gophertunnel は、Minecraft Bedrock Edition がトランスポート層で使用するネットワークプロトコルを minecraft.Network インターフェースとして抽象化しています。


サポートされるネットワークドライバ

Dialer.Dial(network, address)ListenConfig.Listen(network, address) の第1引数に渡すプロトコル名として、以下が標準登録されています。

ネットワーク名実装特徴・用途
"raknet"github.com/sandertv/go-raknetBedrock の標準通信プロトコル(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", "...") で透過的に独自の通信路を利用できるようになります。

Released under the MIT License.