Provide official ListPingHandler implementation

This commit is contained in:
Tnze
2021-12-08 13:18:24 +08:00
parent 2274463c6c
commit 1c2332d678
4 changed files with 135 additions and 77 deletions

View File

@ -1,10 +1,8 @@
package main
import (
"container/list"
_ "embed"
"log"
"sync"
"github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/data/packetid"
@ -16,98 +14,46 @@ import (
)
type MyServer struct {
PlayerList *list.List
PlayerListLock sync.Mutex
server.MojangLoginHandler
Settings struct {
Name string
MaxPlayer int
MOTD chat.Message
}
*server.PlayerList
}
func main() {
var ms MyServer
ms.PlayerList = list.New()
ms.MojangLoginHandler.OnlineMode = true
ms.MojangLoginHandler.Threshold = 256
const MaxPlayer = 20
ms.Settings.Name = "MyServer"
ms.Settings.MaxPlayer = 1
ms.Settings.MOTD = chat.Message{Text: "A Minecraft Server ", Extra: []chat.Message{{Text: "Powered by go-mc", Color: "yellow"}}}
func main() {
motd := &chat.Message{Text: "A Minecraft Server ", Extra: []chat.Message{{Text: "Powered by go-mc", Color: "yellow"}}}
ms := MyServer{
PlayerList: server.NewPlayerList("MyServer", server.ProtocolVersion, MaxPlayer, motd),
}
s := server.Server{
ListPingHandler: &ms,
LoginHandler: &ms,
GamePlay: &ms,
ListPingHandler: ms.PlayerList,
LoginHandler: &server.MojangLoginHandler{
OnlineMode: true,
Threshold: 256,
},
GamePlay: &ms,
}
if err := s.Listen(":25565"); err != nil {
log.Fatalf("Listen error: %v", err)
}
}
func (m *MyServer) Name() string {
return m.Settings.Name
}
func (m *MyServer) Protocol() int {
return server.ProtocolVersion
}
func (m *MyServer) MaxPlayer() int {
return m.Settings.MaxPlayer
}
func (m *MyServer) OnlinePlayer() int {
m.PlayerListLock.Lock()
defer m.PlayerListLock.Unlock()
return m.PlayerList.Len()
}
func (m *MyServer) PlayerSamples() (sample []server.PlayerSample) {
m.PlayerListLock.Lock()
defer m.PlayerListLock.Unlock()
// get first 10 players
sample = make([]server.PlayerSample, 0, 10)
v := m.PlayerList.Front()
for i := 0; i < 10; i++ {
if v == nil {
break
}
sample = append(sample, v.Value.(server.PlayerSample))
v = v.Next()
}
return
}
func (m *MyServer) Description() chat.Message {
return m.Settings.MOTD
}
func (m *MyServer) AcceptPlayer(name string, id uuid.UUID, protocol int32, conn *net.Conn) {
// Add player into PlayerList
m.PlayerListLock.Lock()
if m.PlayerList.Len() >= m.Settings.MaxPlayer {
remove := m.TryInsert(server.PlayerSample{
Name: name,
ID: id,
})
if remove == nil {
err := conn.WritePacket(pk.Marshal(packetid.KickDisconnect,
chat.TranslateMsg("multiplayer.disconnect.server_full"),
))
if err != nil {
log.Printf("Write packet fail: %v", err)
}
m.PlayerListLock.Unlock()
return
}
elem := m.PlayerList.PushBack(server.PlayerSample{
Name: name,
ID: id,
})
m.PlayerListLock.Unlock()
defer func() {
m.PlayerListLock.Lock()
defer m.PlayerListLock.Unlock()
// remove player in PlayerList
m.PlayerList.Remove(elem)
}()
defer remove()
if err := m.joinGame(conn); err != nil {
log.Printf("Write packet fail: %v", err)
@ -148,7 +94,7 @@ func (m *MyServer) joinGame(conn *net.Conn) error {
pk.NBT(nbt.StringifiedMessage(dimensionSNBT)), // Dimension
pk.Identifier("world"), // World Name
pk.Long(0), // Hashed Seed
pk.VarInt(m.Settings.MaxPlayer), // Max Players
pk.VarInt(MaxPlayer), // Max Players
pk.VarInt(15), // View Distance
pk.VarInt(15), // Simulation Distance
pk.Boolean(false), // Reduced Debug Info