75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
// Package server provide a minecraft server framework.
|
|
// You can build the server you want by combining the various functional modules provided here.
|
|
// An example can be found in examples/frameworkServer.
|
|
//
|
|
// This package is under rapid development, and any API may be subject to break changes
|
|
//
|
|
// A server is roughly divided into two parts: Gate and GamePlay
|
|
//
|
|
// +---------------------------------------------------------------------+
|
|
// | Go-MC Server Framework |
|
|
// +--------------------------------------+------------------------------+
|
|
// | Gate | GamePlay |
|
|
// +--------------------+-----------------+ |
|
|
// | LoginHandler | ListPingHandler | |
|
|
// +--------------------+------------+----+---------------+--------------+
|
|
// | MojangLoginHandler | PingInfo | PlayerList | Others.... |
|
|
// +--------------------+------------+--------------------+--------------+
|
|
//
|
|
// Gate, which is used to respond to the client login request, provide login verification,
|
|
// respond to the List Ping Request and providing the online players' information.
|
|
//
|
|
// Gameplay, which is used to handle all things after a player successfully logs in
|
|
// (that is, after the LoginSuccess package is sent),
|
|
// and is responsible for functions including player status, chunk management, keep alive, chat, etc.
|
|
//
|
|
// The implement of Gameplay will provide later.
|
|
package server
|
|
|
|
import (
|
|
"github.com/Tnze/go-mc/net"
|
|
)
|
|
|
|
const ProtocolName = "1.18.1"
|
|
const ProtocolVersion = 757
|
|
|
|
type Server struct {
|
|
ListPingHandler
|
|
LoginHandler
|
|
GamePlay
|
|
}
|
|
|
|
func (s *Server) Listen(addr string) error {
|
|
listener, err := net.ListenMC(addr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for {
|
|
conn, err := listener.Accept()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
go s.acceptConn(&conn)
|
|
}
|
|
}
|
|
|
|
func (s *Server) acceptConn(conn *net.Conn) {
|
|
defer conn.Close()
|
|
protocol, intention, err := s.handshake(conn)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
switch intention {
|
|
case 1: // list ping
|
|
s.acceptListPing(conn)
|
|
case 2: // login
|
|
name, id, err := s.AcceptLogin(conn, protocol)
|
|
if err != nil {
|
|
return
|
|
}
|
|
s.AcceptPlayer(name, id, protocol, conn)
|
|
}
|
|
}
|