minecraft

package
v1.34.1 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2023 License: MIT Imports: 35 Imported by: 110

Documentation

Overview

Package minecraft implements Minecraft Bedrock Edition connections. It implements a Dial() function to dial a connection to a Minecraft server and a Listen() function to create a listener in order to listen for incoming Minecraft connections. Typically these connections are done over RakNet, which is implemented by the github.com/sandertv/go-raknet package.

The minecraft package provides a high level abstraction over Minecraft network related features. It handles the authentication, encryption and spawning sequence by itself and users can send and read packets implemented in the minecraft/protocol/packet package.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultProtocol = proto{}

DefaultProtocol is the Protocol implementation using as default, In default it is current protocol, version and packet pool and does not convert any packets, as they are already of the right type.

Functions

func RegisterNetwork

func RegisterNetwork(id string, n Network)

RegisterNetwork registers a network so that it can be used for Gophertunnel.

Types

type ByteReader added in v1.33.0

type ByteReader interface {
	io.Reader
	io.ByteReader
}

type ByteWriter added in v1.33.0

type ByteWriter interface {
	io.Writer
	io.ByteWriter
}

type Conn

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

Conn represents a Minecraft (Bedrock Edition) connection over a specific net.Conn transport layer. Its methods (Read, Write etc.) are safe to be called from multiple goroutines simultaneously, but ReadPacket must not be called on multiple goroutines simultaneously.

func Dial

func Dial(network, address string) (*Conn, error)

Dial dials a Minecraft connection to the address passed over the network passed. The network is typically "raknet". A Conn is returned which may be used to receive packets from and send packets to.

A zero value of a Dialer struct is used to initiate the connection. A custom Dialer may be used to specify additional behaviour.

Example
package main

import (
	"fmt"
	"github.com/sandertv/gophertunnel/minecraft"
	"github.com/sandertv/gophertunnel/minecraft/auth"
	"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)

func main() {
	// Create a minecraft.Dialer with an auth.TokenSource to authenticate to the server.
	dialer := minecraft.Dialer{
		TokenSource: auth.TokenSource,
	}
	// Dial a new connection to the target server.
	address := "mco.mineplex.com:19132"
	conn, err := dialer.Dial("raknet", address)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	// Make the client spawn in the world: This is a blocking operation that will return an error if the
	// client times out while spawning.
	if err := conn.DoSpawn(); err != nil {
		panic(err)
	}

	// You will then want to start a for loop that reads packets from the connection until it is closed.
	for {
		// Read a packet from the connection: ReadPacket returns an error if the connection is closed or if
		// a read timeout is set. You will generally want to return or break if this happens.
		pk, err := conn.ReadPacket()
		if err != nil {
			break
		}

		// The pk variable is of type packet.Packet, which may be type asserted to gain access to the data
		// they hold:
		switch p := pk.(type) {
		case *packet.Emote:
			fmt.Printf("Emote packet received: %v\n", p.EmoteID)
		case *packet.MovePlayer:
			fmt.Printf("Player %v moved to %v\n", p.EntityRuntimeID, p.Position)
		}

		// Write a packet to the connection: Similarly to ReadPacket, WritePacket will (only) return an error
		// if the connection is closed.
		p := &packet.RequestChunkRadius{ChunkRadius: 32}
		if err := conn.WritePacket(p); err != nil {
			break
		}
	}
}
Output:

func DialContext

func DialContext(ctx context.Context, network, address string) (*Conn, error)

DialContext dials a Minecraft connection to the address passed over the network passed. The network is typically "raknet". A Conn is returned which may be used to receive packets from and send packets to. If a connection is not established before the context passed is cancelled, DialContext returns an error. DialContext uses a zero value of Dialer to initiate the connection.

func DialTimeout

func DialTimeout(network, address string, timeout time.Duration) (*Conn, error)

DialTimeout dials a Minecraft connection to the address passed over the network passed. The network is typically "raknet". A Conn is returned which may be used to receive packets from and send packets to. If a connection is not established before the timeout ends, DialTimeout returns an error. DialTimeout uses a zero value of Dialer to initiate the connection.

func (*Conn) Authenticated

func (conn *Conn) Authenticated() bool

Authenticated returns true if the connection was authenticated through XBOX Live services.

func (*Conn) ChunkRadius

func (conn *Conn) ChunkRadius() int

ChunkRadius returns the initial chunk radius of the connection. For connections obtained through a Listener, this is the radius that the client requested. For connections obtained through a Dialer, this is the radius that the server approved upon.

func (*Conn) ClientCacheEnabled

func (conn *Conn) ClientCacheEnabled() bool

ClientCacheEnabled checks if the connection has the client blob cache enabled. If true, the server may send blobs to the client to reduce network transmission, but if false, the client does not support it, and the server must send chunks as usual.

func (*Conn) ClientData

func (conn *Conn) ClientData() login.ClientData

ClientData returns the client data the client connected with. Note that this client data may be changed during the session, so the data should only be used directly after connection, and should be updated after that by the caller.

func (*Conn) Close

func (conn *Conn) Close() error

Close closes the Conn and its underlying connection. Before closing, it also calls Flush() so that any packets currently pending are sent out.

func (*Conn) DoSpawn

func (conn *Conn) DoSpawn() error

DoSpawn starts the game for the client in the server. DoSpawn should be called for a Conn obtained using minecraft.Dial(). Use Conn.StartGame to spawn a Conn obtained using a minecraft.Listener. DoSpawn will start the spawning sequence using the game data found in conn.GameData(), which was sent earlier by the server. DoSpawn has a default timeout of 1 minute. DoSpawnContext or DoSpawnTimeout may be used for cancellation at any other times.

func (*Conn) DoSpawnContext

func (conn *Conn) DoSpawnContext(ctx context.Context) error

DoSpawnContext starts the game for the client in the server, using a specific context for cancellation. DoSpawnContext should be called for a Conn obtained using minecraft.Dial(). Use Conn.StartGame to spawn a Conn obtained using a minecraft.Listener. DoSpawnContext will start the spawning sequence using the game data found in conn.GameData(), which was sent earlier by the server.

func (*Conn) DoSpawnTimeout

func (conn *Conn) DoSpawnTimeout(timeout time.Duration) error

DoSpawnTimeout starts the game for the client in the server with a timeout after which an error is returned if the client has not yet spawned by that time. DoSpawnTimeout should be called for a Conn obtained using minecraft.Dial(). Use Conn.StartGame to spawn a Conn obtained using a minecraft.Listener. DoSpawnTimeout will start the spawning sequence using the game data found in conn.GameData(), which was sent earlier by the server.

func (*Conn) Flush

func (conn *Conn) Flush() error

Flush flushes the packets currently buffered by the connections to the underlying net.Conn, so that they are directly sent.

func (*Conn) GameData

func (conn *Conn) GameData() GameData

GameData returns specific game data set to the connection for the player to be initialised with. If the Conn is obtained using Listen, this game data may be set to the Listener. If obtained using Dial, the data is obtained from the server.

func (*Conn) IdentityData

func (conn *Conn) IdentityData() login.IdentityData

IdentityData returns the identity data of the connection. It holds the UUID, XUID and username of the connected client.

func (*Conn) Latency

func (conn *Conn) Latency() time.Duration

Latency returns a rolling average of latency between the sending and the receiving end of the connection. The latency returned is updated continuously and is half the round trip time (RTT).

func (*Conn) LocalAddr

func (conn *Conn) LocalAddr() net.Addr

LocalAddr returns the local address of the underlying connection.

func (*Conn) Read

func (conn *Conn) Read(b []byte) (n int, err error)

Read reads a packet from the connection into the byte slice passed, provided the byte slice is big enough to carry the full packet. It is recommended to use ReadPacket() rather than Read() in cases where reading is done directly.

func (*Conn) ReadPacket

func (conn *Conn) ReadPacket() (pk packet.Packet, err error)

ReadPacket reads a packet from the Conn, depending on the packet ID that is found in front of the packet data. If a read deadline is set, an error is returned if the deadline is reached before any packet is received. ReadPacket must not be called on multiple goroutines simultaneously.

If the packet read was not implemented, a *packet.Unknown is returned, containing the raw payload of the packet read.

func (*Conn) RemoteAddr

func (conn *Conn) RemoteAddr() net.Addr

RemoteAddr returns the remote address of the underlying connection.

func (*Conn) ResourcePacks

func (conn *Conn) ResourcePacks() []*resource.Pack

ResourcePacks returns a slice of all resource packs the connection holds. For a Conn obtained using a Listener, this holds all resource packs set to the Listener. For a Conn obtained using Dial, the resource packs include all packs sent by the server connected to.

func (*Conn) SetDeadline

func (conn *Conn) SetDeadline(t time.Time) error

SetDeadline sets the read and write deadline of the connection. It is equivalent to calling SetReadDeadline and SetWriteDeadline at the same time.

func (*Conn) SetReadDeadline

func (conn *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline of the Conn to the time passed. The time must be after time.Now(). Passing an empty time.Time to the method (time.Time{}) results in the read deadline being cleared.

func (*Conn) SetWriteDeadline

func (conn *Conn) SetWriteDeadline(time.Time) error

SetWriteDeadline is a stub function to implement net.Conn. It has no functionality.

func (*Conn) StartGame

func (conn *Conn) StartGame(data GameData) error

StartGame starts the game for a client that connected to the server. StartGame should be called for a Conn obtained using a minecraft.Listener. The game data passed will be used to spawn the player in the world of the server. To spawn a Conn obtained from a call to minecraft.Dial(), use Conn.DoSpawn().

func (*Conn) StartGameContext

func (conn *Conn) StartGameContext(ctx context.Context, data GameData) error

StartGameContext starts the game for a client that connected to the server, returning an error if the context is closed while spawning the client. StartGameContext should be called for a Conn obtained using a minecraft.Listener. The game data passed will be used to spawn the player in the world of the server. To spawn a Conn obtained from a call to minecraft.Dial(), use Conn.DoSpawn().

func (*Conn) StartGameTimeout

func (conn *Conn) StartGameTimeout(data GameData, timeout time.Duration) error

StartGameTimeout starts the game for a client that connected to the server, returning an error if the connection is not yet fully connected while the timeout expires. StartGameTimeout should be called for a Conn obtained using a minecraft.Listener. The game data passed will be used to spawn the player in the world of the server. To spawn a Conn obtained from a call to minecraft.Dial(), use Conn.DoSpawn().

func (*Conn) Write

func (conn *Conn) Write(b []byte) (n int, err error)

Write writes a slice of serialised packet data to the Conn. The data is buffered until the next 20th of a tick, after which it is flushed to the connection. Write returns the amount of bytes written n.

func (*Conn) WritePacket

func (conn *Conn) WritePacket(pk packet.Packet) error

WritePacket encodes the packet passed and writes it to the Conn. The encoded data is buffered until the next 20th of a second, after which the data is flushed and sent over the connection.

type Dialer

type Dialer struct {
	// ErrorLog is a log.Logger that errors that occur during packet handling of servers are written to. By
	// default, ErrorLog is set to one equal to the global logger.
	ErrorLog *log.Logger

	// ClientData is the client data used to login to the server with. It includes fields such as the skin,
	// locale and UUIDs unique to the client. If empty, a default is sent produced using defaultClientData().
	ClientData login.ClientData
	// IdentityData is the identity data used to login to the server with. It includes the username, UUID and
	// XUID of the player.
	// The IdentityData object is obtained using Minecraft auth if Email and Password are set. If not, the
	// object provided here is used, or a default one if left empty.
	IdentityData login.IdentityData

	// TokenSource is the source for Microsoft Live Connect tokens. If set to a non-nil oauth2.TokenSource,
	// this field is used to obtain tokens which in turn are used to authenticate to XBOX Live.
	// The minecraft/auth package provides an oauth2.TokenSource implementation (auth.tokenSource) to use
	// device auth to login.
	// If TokenSource is nil, the connection will not use authentication.
	TokenSource oauth2.TokenSource

	// PacketFunc is called whenever a packet is read from or written to the connection returned when using
	// Dialer.Dial(). It includes packets that are otherwise covered in the connection sequence, such as the
	// Login packet. The function is called with the header of the packet and its raw payload, the address
	// from which the packet originated, and the destination address.
	PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr)

	// DownloadResourcePack is called individually for every texture and behaviour pack sent by the connection when
	// using Dialer.Dial(), and can be used to stop the pack from being downloaded. The function is called with the UUID
	// and version of the resource pack, the number of the current pack being downloaded, and the total amount of packs.
	// The boolean returned determines if the pack will be downloaded or not.
	DownloadResourcePack func(id uuid.UUID, version string, current, total int) bool

	// DisconnectOnUnknownPackets specifies if the connection should disconnect if packets received are not present
	// in the packet pool. If true, such packets lead to the connection being closed immediately.
	// If set to false, the packets will be returned as a packet.Unknown.
	DisconnectOnUnknownPackets bool

	// DisconnectOnInvalidPackets specifies if invalid packets (either too few bytes or too many bytes) should be
	// allowed. If true, such packets lead to the connection being closed immediately. If false,
	// packets with too many bytes will be returned while packets with too few bytes will be skipped.
	DisconnectOnInvalidPackets bool

	// Protocol is the Protocol version used to communicate with the target server. By default, this field is
	// set to the current protocol as implemented in the minecraft/protocol package. Note that packets written
	// to and read from the Conn are always any of those found in the protocol/packet package, as packets
	// are converted from and to this Protocol.
	Protocol Protocol

	// FlushRate is the rate at which packets sent are flushed. Packets are buffered for a duration up to
	// FlushRate and are compressed/encrypted together to improve compression ratios. The lower this
	// time.Duration, the lower the latency but the less efficient both network and cpu wise.
	// The default FlushRate (when set to 0) is time.Second/20. If FlushRate is set negative, packets
	// will not be flushed automatically. In this case, calling `(*Conn).Flush()` is required after any
	// calls to `(*Conn).Write()` or `(*Conn).WritePacket()` to send the packets over network.
	FlushRate time.Duration

	// EnableClientCache, if set to true, enables the client blob cache for the client. This means that the
	// server will send chunks as blobs, which may be saved by the client so that chunks don't have to be
	// transmitted every time, resulting in less network transmission.
	EnableClientCache bool

	// KeepXBLIdentityData, if set to true, enables passing XUID and title ID to the target server
	// if the authentication token is not set. This is technically not valid and some servers might kick
	// the client when an XUID is present without logging in.
	// For getting this to work with BDS, authentication should be disabled.
	KeepXBLIdentityData bool
}

Dialer allows specifying specific settings for connection to a Minecraft server. The zero value of Dialer is used for the package level Dial function.

func (Dialer) Dial

func (d Dialer) Dial(network, address string) (*Conn, error)

Dial dials a Minecraft connection to the address passed over the network passed. The network is typically "raknet". A Conn is returned which may be used to receive packets from and send packets to.

func (Dialer) DialContext

func (d Dialer) DialContext(ctx context.Context, network, address string) (conn *Conn, err error)

DialContext dials a Minecraft connection to the address passed over the network passed. The network is typically "raknet". A Conn is returned which may be used to receive packets from and send packets to. If a connection is not established before the context passed is cancelled, DialContext returns an error.

func (Dialer) DialTimeout

func (d Dialer) DialTimeout(network, address string, timeout time.Duration) (*Conn, error)

DialTimeout dials a Minecraft connection to the address passed over the network passed. The network is typically "raknet". A Conn is returned which may be used to receive packets from and send packets to. If a connection is not established before the timeout ends, DialTimeout returns an error.

type DisconnectError

type DisconnectError string

DisconnectError is an error returned by operations from Conn when the connection is closed by the other end through a packet.Disconnect. It is wrapped in a net.OpError and may be obtained using errors.Unwrap(net.OpError).

func (DisconnectError) Error

func (d DisconnectError) Error() string

Error returns the message held in the packet.Disconnect.

type ForeignStatusProvider

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

ForeignStatusProvider is a ServerStatusProvider that provides the status of a target server to the Listener so that the MOTD, player count etc. is copied.

func NewForeignStatusProvider

func NewForeignStatusProvider(addr string) (*ForeignStatusProvider, error)

NewForeignStatusProvider creates a ForeignStatusProvider that uses the status of the server running at the target address. An error is returned if the address is invalid. Close must be called if the ForeignStatusProvider is discarded.

func (*ForeignStatusProvider) Close

func (f *ForeignStatusProvider) Close() error

Close closes the ForeignStatusProvider and stops polling it. Close always returns nil.

func (*ForeignStatusProvider) ServerStatus

func (f *ForeignStatusProvider) ServerStatus(int, int) ServerStatus

ServerStatus returns the ServerStatus of the target server.

type GameData

type GameData struct {
	// WorldName is the name of the world that the player spawns in. This name will be displayed at the top of
	// the player list when opening the in-game menu. It may contain colour codes and does not have to be an
	// actual world name, but instead, can be the server name.
	// If WorldName is left empty, the name of the Listener will be used to show above the player list
	// in-game.
	WorldName string
	// WorldSeed is the seed used to generate the world. Unlike in PC edition, the seed is a 32bit integer
	// here.
	WorldSeed int64
	// Difficulty is the difficulty of the world that the player spawns in. A difficulty of 0, peaceful, means
	// the player will automatically regenerate health and hunger.
	Difficulty int32
	// EntityUniqueID is the unique ID of the player. The unique ID is unique for the entire world and is
	// often used in packets. Most servers send an EntityUniqueID equal to the EntityRuntimeID.
	EntityUniqueID int64
	// EntityRuntimeID is the runtime ID of the player. The runtime ID is unique for each world session, and
	// entities are generally identified in packets using this runtime ID.
	EntityRuntimeID uint64
	// PlayerGameMode is the game mode the player currently has. It is a value from 0-4, with 0 being
	// survival mode, 1 being creative mode, 2 being adventure mode, 3 being survival spectator and 4 being
	// creative spectator.
	// This field may be set to 5 to make the client fall back to the game mode set in the WorldGameMode
	// field.
	PlayerGameMode int32
	// PersonaDisabled is true if persona skins are disabled for the current game session.
	PersonaDisabled bool
	// CustomSkinsDisabled is true if custom skins are disabled for the current game session.
	CustomSkinsDisabled bool
	// BaseGameVersion is the version of the game from which Vanilla features will be used. The exact function
	// of this field isn't clear.
	BaseGameVersion string
	// PlayerPosition is the spawn position of the player in the world. In servers this is often the same as
	// the world's spawn position found below.
	PlayerPosition mgl32.Vec3
	// Pitch is the vertical rotation of the player. Facing straight forward yields a pitch of 0. Pitch is
	// measured in degrees.
	Pitch float32
	// Yaw is the horizontal rotation of the player. Yaw is also measured in degrees.
	Yaw float32
	// Dimension is the ID of the dimension that the player spawns in. It is a value from 0-2, with 0 being
	// the overworld, 1 being the nether and 2 being the end.
	Dimension int32
	// WorldSpawn is the block on which the world spawn of the world. This coordinate has no effect on the
	// place that the client spawns, but it does have an effect on the direction that a compass points.
	WorldSpawn protocol.BlockPos
	// EditorWorldType is a value to dictate the type of editor mode, a special mode recently introduced adding
	// "powerful tools for editing worlds, intended for experienced creators."
	EditorWorldType int32
	// CreatedInEditor is a value to dictate if the world was created as a project in the editor mode. The functionality
	// of this field is currently unknown.
	CreatedInEditor bool
	// ExportedFromEditor is a value to dictate if the world was exported from editor mode. The functionality of this
	// field is currently unknown.
	ExportedFromEditor bool
	// WorldGameMode is the game mode that a player gets when it first spawns in the world. It is shown in the
	// settings and is used if the PlayerGameMode is set to 5.
	WorldGameMode int32
	// GameRules defines game rules currently active with their respective values. The value of these game
	// rules may be either 'bool', 'int32' or 'float32'. Some game rules are server side only, and don't
	// necessarily need to be sent to the client.
	GameRules []protocol.GameRule
	// Time is the total time that has elapsed since the start of the world.
	Time int64
	// ServerBlockStateChecksum is a checksum to ensure block states between the server and client match.
	// This can simply be left empty, and the client will avoid trying to verify it.
	ServerBlockStateChecksum uint64
	// CustomBlocks is a list of custom blocks added to the game by the server. These blocks all have a name
	// and block properties.
	CustomBlocks []protocol.BlockEntry
	// Items is a list of all items existing in the game, including custom items registered by the server.
	Items []protocol.ItemEntry
	// PlayerMovementSettings specify the different server authoritative movement settings that it has
	// enabled.
	PlayerMovementSettings protocol.PlayerMovementSettings
	// ServerAuthoritativeInventory specifies if the server authoritative inventory system is enabled. This
	// is a new system introduced in 1.16. Backwards compatibility with the inventory transactions has to
	// some extent been preserved, but will eventually be removed.
	ServerAuthoritativeInventory bool
	// Experiments is a list of experiments enabled on the server side. These experiments are used to enable
	// disable experimental features.
	Experiments []protocol.ExperimentData
	// PlayerPermissions is the permission level of the player. It is a value from 0-3, with 0 being visitor,
	// 1 being member, 2 being operator and 3 being custom.
	PlayerPermissions int32
	// ChunkRadius is the initial chunk radius that the connection gets. This can be changed later on using a
	// packet.ChunkRadiusUpdated.
	ChunkRadius int32
	// ClientSideGeneration is true if the client should use the features registered in the FeatureRegistry packet to
	// generate terrain client-side to save on bandwidth.
	ClientSideGeneration bool
	// ChatRestrictionLevel specifies the level of restriction on in-game chat. It is one of the constants above.
	ChatRestrictionLevel uint8
	// DisablePlayerInteractions is true if the client should ignore other players when interacting with the world.
	DisablePlayerInteractions bool
	// UseBlockNetworkIDHashes is true if the client should use the hash of a block's name as its network ID rather than
	// its index in the expected block palette. This is useful for servers that wish to support multiple protocol versions
	// and custom blocks, but it will result in extra bytes being written for every block in a sub chunk palette.
	UseBlockNetworkIDHashes bool
}

GameData is a loose wrapper around a part of the data found in the StartGame packet. It holds data sent specifically at the start of the game, such as the position of the player, the game mode, etc.

type ListenConfig

type ListenConfig struct {
	// ErrorLog is a log.Logger that errors that occur during packet handling of clients are written to. By
	// default, ErrorLog is set to one equal to the global logger.
	ErrorLog *log.Logger

	// AuthenticationDisabled specifies if authentication of players that join is disabled. If set to true, no
	// verification will be done to ensure that the player connecting is authenticated using their XBOX Live
	// account.
	AuthenticationDisabled bool

	// MaximumPlayers is the maximum amount of players accepted in the server. If non-zero, players that
	// attempt to join while the server is full will be kicked during login. If zero, the maximum player count
	// will be dynamically updated each time a player joins, so that an unlimited amount of players is
	// accepted into the server.
	MaximumPlayers int

	// AllowUnknownPackets specifies if connections of this Listener are allowed to send packets not present
	// in the packet pool. If false (by default), such packets lead to the connection being closed immediately.
	// If set to true, the packets will be returned as a packet.Unknown.
	AllowUnknownPackets bool

	// AllowInvalidPackets specifies if invalid packets (either too few bytes or too many bytes) should be
	// allowed. If false (by default), such packets lead to the connection being closed immediately. If true,
	// packets with too many bytes will be returned while packets with too few bytes will be skipped.
	AllowInvalidPackets bool

	// StatusProvider is the ServerStatusProvider of the Listener. When set to nil, the default provider,
	// ListenerStatusProvider, is used as provider.
	StatusProvider ServerStatusProvider

	// AcceptedProtocols is a slice of Protocol accepted by a Listener created with this ListenConfig. The current
	// Protocol is always added to this slice. Clients with a protocol version that is not present in this slice will
	// be disconnected.
	AcceptedProtocols []Protocol
	// Compression is the packet.Compression to use for packets sent over this Conn. If set to nil, the compression
	// will default to packet.flateCompression.
	Compression packet.Compression // TODO: Change this to snappy once Windows crashes are resolved.
	// FlushRate is the rate at which packets sent are flushed. Packets are buffered for a duration up to
	// FlushRate and are compressed/encrypted together to improve compression ratios. The lower this
	// time.Duration, the lower the latency but the less efficient both network and cpu wise.
	// The default FlushRate (when set to 0) is time.Second/20. If FlushRate is set negative, packets
	// will not be flushed automatically. In this case, calling `(*Conn).Flush()` is required after any
	// calls to `(*Conn).Write()` or `(*Conn).WritePacket()` to send the packets over network.
	FlushRate time.Duration

	// ResourcePacks is a slice of resource packs that the listener may hold. Each client will be asked to
	// download these resource packs upon joining.
	// This field should not be edited during runtime of the Listener to avoid race conditions. Use
	// Listener.AddResourcePack() to add a resource pack after having called Listener.Listen().
	ResourcePacks []*resource.Pack
	// Biomes contains information about all biomes that the server has registered, which the client can use
	// to render the world more effectively. If these are nil, the default biome definitions will be used.
	Biomes map[string]any
	// TexturePacksRequired specifies if clients that join must accept the texture pack in order for them to
	// be able to join the server. If they don't accept, they can only leave the server.
	TexturePacksRequired bool

	// PacketFunc is called whenever a packet is read from or written to a connection returned when using
	// Listener.Accept. It includes packets that are otherwise covered in the connection sequence, such as the
	// Login packet. The function is called with the header of the packet and its raw payload, the address
	// from which the packet originated, and the destination address.
	PacketFunc func(header packet.Header, payload []byte, src, dst net.Addr)
}

ListenConfig holds settings that may be edited to change behaviour of a Listener.

func (ListenConfig) Listen

func (cfg ListenConfig) Listen(network string, address string) (*Listener, error)

Listen announces on the local network address. The network is typically "raknet". If the host in the address parameter is empty or a literal unspecified IP address, Listen listens on all available unicast and anycast IP addresses of the local system.

type Listener

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

Listener implements a Minecraft listener on top of an unspecific net.Listener. It abstracts away the login sequence of connecting clients and provides the implements the net.Listener interface to provide a consistent API.

func Listen

func Listen(network, address string) (*Listener, error)

Listen announces on the local network address. The network must be "tcp", "tcp4", "tcp6", "unix", "unixpacket" or "raknet". A Listener is returned which may be used to accept connections. If the host in the address parameter is empty or a literal unspecified IP address, Listen listens on all available unicast and anycast IP addresses of the local system. Listen has the default values for the fields of Listener filled out. To use different values for these fields, call &Listener{}.Listen() instead.

Example
package main

import (
	"fmt"
	"github.com/sandertv/gophertunnel/minecraft"
	"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)

func main() {
	// Create a minecraft.Listener with a specific name to be displayed as MOTD in the server list.
	name := "MOTD of this server"
	cfg := minecraft.ListenConfig{
		StatusProvider: minecraft.NewStatusProvider(name),
	}

	// Listen on the address with port 19132.
	address := ":19132"
	listener, err := cfg.Listen("raknet", address)
	if err != nil {
		panic(err)
	}

	for {
		// Accept connections in a for loop. Accept will only return an error if the minecraft.Listener is
		// closed. (So never unexpectedly.)
		c, err := listener.Accept()
		if err != nil {
			return
		}
		conn := c.(*minecraft.Conn)

		go func() {
			// Process the connection on another goroutine as you would with TCP connections.
			defer conn.Close()

			// Make the client spawn in the world using conn.StartGame. An error is returned if the client
			// times out during the connection.
			worldData := minecraft.GameData{ /* World data here */ }
			if err := conn.StartGame(worldData); err != nil {
				return
			}

			for {
				// Read a packet from the connection: ReadPacket returns an error if the connection is closed or if
				// a read timeout is set. You will generally want to return or break if this happens.
				pk, err := conn.ReadPacket()
				if err != nil {
					break
				}

				// The pk variable is of type packet.Packet, which may be type asserted to gain access to the data
				// they hold:
				switch p := pk.(type) {
				case *packet.Emote:
					fmt.Printf("Emote packet received: %v\n", p.EmoteID)
				case *packet.MovePlayer:
					fmt.Printf("Player %v moved to %v\n", p.EntityRuntimeID, p.Position)
				}

				// Write a packet to the connection: Similarly to ReadPacket, WritePacket will (only) return an error
				// if the connection is closed.
				p := &packet.ChunkRadiusUpdated{ChunkRadius: 32}
				if err := conn.WritePacket(p); err != nil {
					break
				}
			}
		}()
	}
}
Output:

func (*Listener) Accept

func (listener *Listener) Accept() (net.Conn, error)

Accept accepts a fully connected (on Minecraft layer) connection which is ready to receive and send packets. It is recommended to cast the net.Conn returned to a *minecraft.Conn so that it is possible to use the Conn.ReadPacket() and Conn.WritePacket() methods. Accept returns an error if the listener is closed.

func (*Listener) Addr

func (listener *Listener) Addr() net.Addr

Addr returns the address of the underlying listener.

func (*Listener) Close

func (listener *Listener) Close() error

Close closes the listener and the underlying net.Listener. Pending calls to Accept will fail immediately.

func (*Listener) Disconnect

func (listener *Listener) Disconnect(conn *Conn, message string) error

Disconnect disconnects a Minecraft Conn passed by first sending a disconnect with the message passed, and closing the connection after. If the message passed is empty, the client will be immediately sent to the server list instead of a disconnect screen.

type ListenerStatusProvider

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

ListenerStatusProvider is the default ServerStatusProvider of a Listener. It displays a static server name/ MOTD and displays the player count and maximum amount of players of the server.

func NewStatusProvider

func NewStatusProvider(serverName string) ListenerStatusProvider

NewStatusProvider creates a ListenerStatusProvider that displays the server name passed.

func (ListenerStatusProvider) ServerStatus

func (l ListenerStatusProvider) ServerStatus(playerCount, maxPlayers int) ServerStatus

ServerStatus ...

type Network

type Network interface {
	// DialContext attempts to dial a connection to the address passed. The address may be either an IP address or a
	// hostname, combined with a port that is separated with ':'.
	// DialContext will use the deadline (ctx.Deadline) of the context.Context passed for the maximum amount of time that
	// the dialing can take. DialContext will terminate as soon as possible when the context.Context is closed.
	DialContext(ctx context.Context, address string) (net.Conn, error)
	// PingContext sends a ping to an address and returns the response obtained. If successful, a non-nil response byte
	// slice containing the data is returned. If the ping failed, an error is returned describing the failure.
	// Note that the packet sent to the server may be lost due to the nature of UDP. If this is the case, PingContext
	// could last indefinitely, hence a timeout should always be attached to the context passed.
	// PingContext cancels as soon as the deadline expires.
	PingContext(ctx context.Context, address string) (response []byte, err error)
	// Listen listens on the address passed and returns a listener that may be used to accept connections. If not
	// successful, an error is returned.
	// The address follows the same rules as those defined in the net.TCPListen() function.
	// Specific features of the listener may be modified once it is returned, such as the used log and/or the
	// accepted protocol.
	Listen(address string) (NetworkListener, error)
}

Network represents an implementation of a supported network layers, such as RakNet.

type NetworkListener

type NetworkListener interface {
	net.Listener
	// ID returns the unique ID of the listener. This ID is usually used by a client to identify a specific
	// server during a single session.
	ID() int64
	// PongData sets the pong data that is used to respond with when a client sends a ping. It usually holds game
	// specific data that is used to display in a server list.
	// If a data slice is set with a size bigger than math.MaxInt16, the function panics.
	PongData(data []byte)
}

NetworkListener represents a listening connection to a remote server. It is the equivalent of net.Listener, but with extra functionality specific to Minecraft.

type Protocol

type Protocol interface {
	// ID returns the unique ID of the Protocol. It generally goes up for every new Minecraft version released.
	ID() int32
	// Ver returns the Minecraft version associated with this Protocol, such as "1.18.10".
	Ver() string
	// Packets returns a packet.Pool with all packets registered for this
	// Protocol. It is used to lookup packets by a packet ID. If listener is set
	// to true, the pool should be created for a Listener. This means that only
	// packets that may be sent by a client should be allowed.
	Packets(listener bool) packet.Pool
	// NewReader returns a protocol.IO that implements reading operations for reading types
	// that are used for this Protocol.
	NewReader(r ByteReader, shieldID int32, enableLimits bool) protocol.IO
	// NewWriter returns a protocol.IO that implements writing operations for writing types
	// that are used for this Protocol.
	NewWriter(w ByteWriter, shieldID int32) protocol.IO
	// ConvertToLatest converts a packet.Packet obtained from the other end of a Conn to a slice of packet.Packets from
	// the latest protocol. Any packet.Packet implementation in the packet.Pool obtained through a call to Packets that
	// is not identical to the most recent version of that packet.Packet must be converted to the most recent version of
	// that packet adequately in this function. ConvertToLatest returns pk if the packet.Packet was unchanged in this
	// version compared to the latest. Note that packets must also be converted if only their ID changes.
	ConvertToLatest(pk packet.Packet, conn *Conn) []packet.Packet
	// ConvertFromLatest converts a packet.Packet of the most recent Protocol to a slice of packet.Packets of this
	// specific Protocol. ConvertFromLatest must be synonymous to ConvertToLatest, in that it should convert any
	// packet.Packet to the correct one from the packet.Pool returned through a call to Packets if its payload or ID was
	// changed in this Protocol compared to the latest one.
	ConvertFromLatest(pk packet.Packet, conn *Conn) []packet.Packet
}

Protocol represents the Minecraft protocol used to communicate over network. It comprises a unique set of packets that may be changed in any version. Protocol specifically handles the conversion of packets between the most recent protocol (as in the minecraft/protocol package) and the protocol as specified in Protocol.

type RakNet

type RakNet struct{}

RakNet is an implementation of a RakNet v10 Network.

func (RakNet) DialContext

func (r RakNet) DialContext(ctx context.Context, address string) (net.Conn, error)

DialContext ...

func (RakNet) Listen

func (r RakNet) Listen(address string) (NetworkListener, error)

Listen ...

func (RakNet) PingContext

func (r RakNet) PingContext(ctx context.Context, address string) (response []byte, err error)

PingContext ...

type ServerStatus

type ServerStatus struct {
	// ServerName is the name or MOTD of the server, as shown in the server list.
	ServerName string
	// PlayerCount is the current amount of players displayed in the list.
	PlayerCount int
	// MaxPlayers is the maximum amount of players in the server. If set to 0, MaxPlayers is set to
	// PlayerCount + 1.
	MaxPlayers int
}

ServerStatus holds the information shown in the Minecraft server list. They have no impact on the listener functionality-wise.

type ServerStatusProvider

type ServerStatusProvider interface {
	// ServerStatus returns the server status which includes the MOTD/server name, amount of online players
	// and the amount of maximum players.
	// The player count and max players of the minecraft.Listener that calls this method is passed.
	ServerStatus(playerCount, maxPlayers int) ServerStatus
}

ServerStatusProvider represents a type that is able to provide the visual status of a server, in specific its MOTD, the amount of online players and the player limit displayed in the server list. These providers may be used to display different information in the server list. Although they overwrite the maximum players and online players maintained by a Listener in the server list, these values are not changed and will still be used internally to check if players are able to be connected. Players will still be disconnected if the maximum player count as set in the ListenConfig.MaximumPlayers field of a Listener is reached (unless ListenConfig.MaximumPlayers is 0).

Directories

Path Synopsis
Package auth implements authentication to Microsoft Live Connect accounts, XBOX Live accounts and ultimately Minecraft accounts associated with them.
Package auth implements authentication to Microsoft Live Connect accounts, XBOX Live accounts and ultimately Minecraft accounts associated with them.
Package nbt implements the NBT formats used by Minecraft Bedrock Edition and Minecraft Java Edition.
Package nbt implements the NBT formats used by Minecraft Bedrock Edition and Minecraft Java Edition.
Package protocol implements structures and functions used to write or read data related to the Minecraft Bedrock Edition protocol.
Package protocol implements structures and functions used to write or read data related to the Minecraft Bedrock Edition protocol.
login
Package login provides functions to decode and encode Minecraft login requests found in the Login packet connection request.
Package login provides functions to decode and encode Minecraft login requests found in the Login packet connection request.
packet
Package packet implements every packet in the Minecraft Bedrock Edition protocol using the functions found in the minecraft/protocol package.
Package packet implements every packet in the Minecraft Bedrock Edition protocol using the functions found in the minecraft/protocol package.
Package resource implements the compiling of resource packs found in files, directories or raw byte data.
Package resource implements the compiling of resource packs found in files, directories or raw byte data.
Package text has utility methods used for formatting text to display in Minecraft, and to convert these colour codes into codes suitable for the command line.
Package text has utility methods used for formatting text to display in Minecraft, and to convert these colour codes into codes suitable for the command line.

Jump to

Keyboard shortcuts

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