plasma

package module
v0.0.0-...-02301d3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 4, 2021 License: MIT Imports: 23 Imported by: 0

README

Plasma

Minecraft server framework written in Go. Having an API similar to the standard http package, this framework allows you to write Minecraft servers from scratch without needing too much boilerplate.

Basic Server

package main

import (
	"github.com/specspace/plasma"
	"github.com/specspace/plasma/protocol"
	"github.com/specspace/plasma/protocol/packets/handshaking"
	"github.com/specspace/plasma/protocol/packets/status"
	"log"
)

func main() {
	plasma.HandleFunc(protocol.StateHandshaking, handshaking.ServerBoundHandshakePacketID, handshakeHandler)
	plasma.HandleFunc(protocol.StateStatus, status.ServerBoundPingPacketID, pingHandler)
	plasma.HandleFunc(protocol.StateStatus, status.ServerBoundRequestPacketID, responseHandler)

	log.Fatal(plasma.ListenAndServe(":25565", nil))
}

func handshakeHandler(w plasma.ResponseWriter, r *plasma.Request) {
	// You can access and unmarshal the handshake packet like this.
	hs, err := handshaking.UnmarshalServerBoundHandshake(r.Packet)
	if err != nil {
		return
	}

	if hs.IsStatusRequest() {
		// We can now update the connection state according to the
		// handshake request packet.
		w.SetState(protocol.StateStatus)
	} else if hs.IsLoginRequest() {
		w.SetState(protocol.StateLogin)
	}
}

func pingHandler(w plasma.ResponseWriter, r *plasma.Request) {
	ping, err := status.UnmarshalServerBoundPing(r.Packet)
	if err != nil {
		return
	}

	pong := status.ClientBoundPong{
		Payload: ping.Payload,
	}

	w.WritePacket(pong.Marshal())
}

func responseHandler(w plasma.ResponseWriter, r *plasma.Request) {
	statusResponse := plasma.StatusResponse{
		Version: plasma.Version{
			Name:           "Plasma 1.16.4",
			ProtocolNumber: 754,
		},
		PlayersInfo: r.Server.PlayersInfo(),
		IconPath:    "",
		MOTD:        "Hello World",
	}

	bb, err := statusResponse.JSON()
	if err != nil {
		return
	}

	w.WritePacket(status.ClientBoundResponse{
		JSONResponse: protocol.String(bb),
	}.Marshal())
}

Documentation

Index

Constants

View Source
const DefaultAddr string = ":25565"

Variables

View Source
var DefaultServeMux = NewServeMux()

Functions

func GenerateSessionHash

func GenerateSessionHash(serverID string, sharedSecret, publicKey []byte) string

func Handle

func Handle(state protocol.State, packetID byte, handler Handler)

func HandleFunc

func HandleFunc(state protocol.State, packetID byte, handler func(w ResponseWriter, r *Request))

func ListenAndServe

func ListenAndServe(addr string, handler Handler) error

func MojangSessionServerURLHasJoined

func MojangSessionServerURLHasJoined(username, sessionHash string) string

func MojangSessionServerURLHasJoinedWithIP

func MojangSessionServerURLHasJoinedWithIP(username, sessionHash, ip string) string

Types

type Conn

type Conn interface {
	net.Conn
	PacketWriter
	PacketReader
	PacketPeeker

	State() protocol.State
	Threshold() int
}

Conn is a minecraft Connection

func Dial

func Dial(addr string) (Conn, error)

Dial create a Minecraft connection

func DialTimeout

func DialTimeout(addr string, timeout time.Duration) (Conn, error)

DialTimeout acts like DialMC but takes a timeout.

type DefaultSessionEncrypter

type DefaultSessionEncrypter struct {
	// contains filtered or unexported fields
}

func (*DefaultSessionEncrypter) DecryptAndVerifySharedSecret

func (encrypter *DefaultSessionEncrypter) DecryptAndVerifySharedSecret(r *Request, sharedSecret, verifyToken []byte) ([]byte, error)

func (*DefaultSessionEncrypter) GenerateVerifyToken

func (encrypter *DefaultSessionEncrypter) GenerateVerifyToken(r *Request) ([]byte, error)

func (*DefaultSessionEncrypter) PublicKey

func (encrypter *DefaultSessionEncrypter) PublicKey() []byte

type Handler

type Handler interface {
	ServeProtocol(w ResponseWriter, r *Request)
}

type HandlerFunc

type HandlerFunc func(w ResponseWriter, r *Request)

func (HandlerFunc) ServeProtocol

func (f HandlerFunc) ServeProtocol(w ResponseWriter, r *Request)

type Listener

type Listener struct {
	net.Listener
}

func Listen

func Listen(addr string) (Listener, error)

func (Listener) Accept

func (l Listener) Accept() (Conn, error)

type MojangSessionAuthenticator

type MojangSessionAuthenticator struct{}

func (*MojangSessionAuthenticator) AuthenticateSession

func (auth *MojangSessionAuthenticator) AuthenticateSession(username, sessionHash string) (Session, error)

func (*MojangSessionAuthenticator) AuthenticateSessionPreventProxy

func (auth *MojangSessionAuthenticator) AuthenticateSessionPreventProxy(username, sessionHash, ip string) (Session, error)

type PacketPeeker

type PacketPeeker interface {
	PeekPacket() (protocol.Packet, error)
}

type PacketReader

type PacketReader interface {
	ReadPacket() (protocol.Packet, error)
}

type PacketWriter

type PacketWriter interface {
	WritePacket(p protocol.Packet) error
}

type Player

type Player interface {
	Conn

	// UUID returns the uuid of the player
	UUID() uuid.UUID

	// Username returns the username of the player
	Username() string

	// Skin returns the Skin of the player
	Skin() Skin
}

type PlayerInfo

type PlayerInfo struct {
	Name string `json:"name"`
	UUID string `json:"id"`
}

type PlayersInfo

type PlayersInfo struct {
	MaxPlayers    int          `json:"max"`
	PlayersOnline int          `json:"online"`
	Players       []PlayerInfo `json:"sample"`
}

type Request

type Request struct {
	Packet protocol.Packet
	// contains filtered or unexported fields
}

func (Request) ClonePacket

func (r Request) ClonePacket() protocol.Packet

ClonePacket makes a deep copy of the packet and returns it.

func (Request) Conn

func (r Request) Conn() Conn

func (*Request) Player

func (r *Request) Player() Player

func (Request) ProtocolState

func (r Request) ProtocolState() protocol.State

func (Request) Server

func (r Request) Server() *Server

func (*Request) UpdatePlayerSkin

func (r *Request) UpdatePlayerSkin(skin Skin)

func (*Request) UpdatePlayerUUID

func (r *Request) UpdatePlayerUUID(uuid uuid.UUID)

func (*Request) UpdatePlayerUsername

func (r *Request) UpdatePlayerUsername(username string)

type ResponseWriter

type ResponseWriter interface {
	PacketWriter
	SetState(state protocol.State)
	SetEncryption(sharedSecret []byte) error
	SetCompression(threshold int)
}

type ServeMux

type ServeMux struct {
	// contains filtered or unexported fields
}

func NewServeMux

func NewServeMux() *ServeMux

func (*ServeMux) Handle

func (mux *ServeMux) Handle(state protocol.State, packetID byte, handler Handler)

func (*ServeMux) HandleFunc

func (mux *ServeMux) HandleFunc(state protocol.State, packetID byte, handler func(w ResponseWriter, r *Request))

func (*ServeMux) Handler

func (mux *ServeMux) Handler(r *Request) (Handler, byte)

func (*ServeMux) ServeProtocol

func (mux *ServeMux) ServeProtocol(w ResponseWriter, r *Request)

type Server

type Server struct {
	ID         string
	Addr       string
	Encryption bool
	MaxPlayers int

	SessionEncrypter     SessionEncrypter
	SessionAuthenticator SessionAuthenticator
	Handler              Handler
	// contains filtered or unexported fields
}

Server defines the struct of a running Minecraft server

func (*Server) AddPlayer

func (srv *Server) AddPlayer(r *Request, username string)

func (*Server) Close

func (srv *Server) Close() error

func (*Server) IsRunning

func (srv *Server) IsRunning() bool

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe() error

func (*Server) Player

func (srv *Server) Player(r *Request) Player

func (*Server) Players

func (srv *Server) Players() []Player

func (*Server) PlayersInfo

func (srv *Server) PlayersInfo() PlayersInfo

type Session

type Session struct {
	PlayerUUID uuid.UUID
	PlayerSkin Skin
}

type SessionAuthenticator

type SessionAuthenticator interface {
	AuthenticateSession(username, sessionHash string) (Session, error)
	AuthenticateSessionPreventProxy(username, sessionHash, ip string) (Session, error)
}

type SessionEncrypter

type SessionEncrypter interface {
	PublicKey() []byte
	GenerateVerifyToken(r *Request) ([]byte, error)
	DecryptAndVerifySharedSecret(r *Request, sharedSecret, verifyToken []byte) ([]byte, error)
}

func NewDefaultSessionEncrypter

func NewDefaultSessionEncrypter() (SessionEncrypter, error)

type Sha1Hash

type Sha1Hash struct {
	hash.Hash
}

func NewSha1Hash

func NewSha1Hash() Sha1Hash

func (Sha1Hash) HexDigest

func (h Sha1Hash) HexDigest() string

func (Sha1Hash) Update

func (h Sha1Hash) Update(b []byte)

type Skin

type Skin struct {
	Value     string
	Signature string
}

type StatusResponse

type StatusResponse struct {
	Version     Version
	PlayersInfo PlayersInfo
	IconPath    string
	MOTD        string
}

func (StatusResponse) JSON

func (sr StatusResponse) JSON() ([]byte, error)

type Version

type Version struct {
	// Name of the version eg. "1.16.5"
	Name string `json:"name"`
	// Protocol version number eg. 754
	ProtocolNumber int `json:"protocol"`
}

Directories

Path Synopsis
_examples
cfb8
All credits go to Ilmari Karonen Source: https://stackoverflow.com/questions/23897809/different-results-in-go-and-pycrypto-when-using-aes-cfb/37234233#37234233
All credits go to Ilmari Karonen Source: https://stackoverflow.com/questions/23897809/different-results-in-go-and-pycrypto-when-using-aes-cfb/37234233#37234233

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL