Skip to content

カスタム待受サーバー

公式クライアント(Bedrock)から接続できる軽量なダミー待受サーバーの実装例です。接続してきたプレイヤーに歓迎チャットを送り、移動やチャット操作に反応します。


完全なコード例

go
package main

import (
	"fmt"
	"log"

	"github.com/go-gl/mathgl/mgl32"
	"github.com/sandertv/gophertunnel/minecraft"
	"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)

func main() {
	// 1. サーバーの待受設定
	status := minecraft.NewStatusProvider("§l§bGo Bedrock Server", "§7gophertunnel による軽量サーバー")
	lc := minecraft.ListenConfig{
		StatusProvider:         status,
		AuthenticationDisabled: true, // 認証オフ(LAN/プライベート接続用)
	}

	listener, err := lc.Listen("raknet", "0.0.0.0:19132")
	if err != nil {
		log.Fatalf("サーバー起動失敗: %v", err)
	}
	defer listener.Close()

	log.Println("Bedrock サーバー待機中: 0.0.0.0:19132")

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Printf("Accept エラー: %v", err)
			continue
		}

		go handlePlayer(conn.(*minecraft.Conn))
	}
}

func handlePlayer(conn *minecraft.Conn) {
	defer conn.Close()

	// 2. StartGame パケットでプレイヤーをワールドに初期化
	err := conn.StartGame(minecraft.GameData{
		WorldName:       "Gopher World",
		PlayerPosition:  mgl32.Vec3{0, 70, 0},
		PlayerGameMode:  packet.GameTypeCreative,
		Dimension:       packet.DimensionOverworld,
		BaseGameVersion: "*",
	})
	if err != nil {
		log.Printf("StartGame エラー: %v", err)
		return
	}

	name := conn.IdentityData().DisplayName
	log.Printf("[+] プレイヤー参加: %s (%s)", name, conn.RemoteAddr())

	// 3. 歓迎メッセージを送信
	_ = conn.WritePacket(&packet.Text{
		TextType: packet.TextTypeRaw,
		Message:  fmt.Sprintf("§aようこそ、§l%s§r§a さん!\n§7このサーバーは gophertunnel で稼働しています。", name),
	})

	// 4. パケット受信ループ
	for {
		pk, err := conn.ReadPacket()
		if err != nil {
			log.Printf("[-] プレイヤー退出: %s", name)
			break
		}

		switch p := pk.(type) {
		case *packet.Text:
			// チャットをブロードキャスト(エコーバック)
			log.Printf("<%s> %s", name, p.Message)
			_ = conn.WritePacket(&packet.Text{
				TextType:   packet.TextTypeChat,
				SourceName: "サーバー",
				Message:    fmt.Sprintf("受信メッセージ: %s", p.Message),
			})

		case *packet.PlayerAction:
			if p.ActionType == packet.PlayerActionJump {
				log.Printf("%s がジャンプしました", name)
			}
		}
	}
}

Released under the MIT License.