Skip to content

サーバー Ping / MOTD 取得

サーバーに接続することなく、RakNet の Unconnected Ping を送信してサーバー名、参加人数、プロトコルバージョン等の情報を取得する実践的なコマンドラインツールのサンプルです。


完全なコード例

go
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/sandertv/gophertunnel/minecraft"
)

func main() {
	var (
		address = flag.String("addr", "play.cubecraft.net:19132", "対象のサーバーアドレス (ホスト:ポート)")
		timeout = flag.Duration("timeout", 4*time.Second, "タイムアウト時間")
	)
	flag.Parse()

	fmt.Printf("サーバー %s へ Ping 送信中...\n", *address)

	ctx, cancel := context.WithTimeout(context.Background(), *timeout)
	defer cancel()

	// 1. RakNet Ping を送信して生の Pong バイト列を取得
	pongBytes, err := minecraft.PingContext(ctx, *address)
	if err != nil {
		log.Fatalf("Ping 失敗 (オフラインまたはタイムアウト): %v", err)
	}

	// 2. Pong バイト列をパース
	status, err := minecraft.ParsePong(pongBytes)
	if err != nil {
		log.Fatalf("Pong 解析失敗: %v", err)
	}

	// 3. 取得結果の表示
	fmt.Println("\n=== サーバー情報 ===")
	fmt.Printf("サーバー名 (MOTD): %s\n", status.ServerName)
	fmt.Printf("サブメッセージ:   %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)
	fmt.Printf("Nintendo 限定:    %t\n", status.NintendoLimited)
	fmt.Printf("サーバー GUID:    %d\n", status.ServerGUID)
}

実行方法

bash
# デフォルト (CubeCraft) へ Ping
go run main.go

# 任意のサーバーへ Ping
go run main.go -addr 127.0.0.1:19132 -timeout 2s

Released under the MIT License.