packet

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2026 License: MIT Imports: 10 Imported by: 0

README

quiver-protocol

Go library for Minecraft Java Edition protocol primitives — VarInt encoding, packet framing, compression, AES/CFB8 encryption, and serialization helpers.

Part of the Quiver project — a Minecraft Java Edition server implementation.

Features

  • VarInt/VarLong encoding/decoding (Minecraft variable-length integers)
  • Packet framing — length-prefixed packet read/write with PacketReader and PacketWriter
  • Compression — zlib compression/decompression with configurable threshold
  • Encryption — RSA 1024-bit key pair generation, AES/CFB8 stream cipher
  • Serialization helpers — VarInt-length-prefixed strings and byte arrays
  • Packet builder — fluent API for constructing outbound packets
  • Registry — global packet registration by (state, direction, ID)
  • State machine — protocol state definitions and handler interface
  • ConnectionContext — per-connection state (encryption, compression, protocol state)

Installation

go get github.com/gauvainw/quiver-protocol

Usage

import protocol "github.com/gauvainw/quiver-protocol"

// Encode a VarInt
data := protocol.VarIntEncode(300)

// Create a packet builder
builder := protocol.NewBuilder()
builder.WriteVarInt(0x00)
builder.WriteString("Hello")
packet, _ := builder.Bytes()

// Create a connection context
ctx := protocol.NewConnectionContext(conn)

Protocol State Machine

Handshaking → Status (server info + ping/pong)
            → Login  (encryption + compression + auth)
                     → Configuration (registry data, feature flags)
                                     → Play (game)

License

MIT

Documentation

Index

Constants

View Source
const (
	// Handshaking
	HandshakePacketID = 0x00

	// Serverbound
	StatusRequestPacketID = 0x00
	PingRequestPacketID   = 0x01
	// Clientbound
	StatusResponsePacketID = 0x00
	PongResponsePacketID   = 0x01
)

Status state packet IDs

View Source
const (
	// Serverbound
	LoginStartPacketID        = 0x00
	LoginEncryptionPacketID   = 0x01
	LoginAcknowledgedPacketID = 0x03

	// Clientbound
	LoginSuccessPacketID     = 0x02
	LoginCompressionPacketID = 0x03 // same value as LoginAcknowledgedPacketID but clientbound
	LoginDisconnectPacketID  = 0x00
)

Login state packet IDs

View Source
const (
	// Serverbound
	ConfigClientInformationPacketID         = 0x00
	ConfigPluginMessageServerPacketID       = 0x02
	ConfigFinishConfigurationServerPacketID = 0x03
	ConfigKnownPacksServerPacketID          = 0x07 // serverbound

	// Clientbound
	ConfigPluginMessageClientPacketID       = 0x01
	ConfigFinishConfigurationClientPacketID = 0x03 // same value as server-side but clientbound
	ConfigRegistryDataPacketID              = 0x07 // clientbound
	ConfigFeatureFlagsPacketID              = 0x0C
	ConfigUpdateTagsPacketID                = 0x0D
	ConfigKnownPacksClientPacketID          = 0x0E
)

Configuration state packet IDs

View Source
const (
	// Serverbound
	PlayConfirmTeleportationPacketID = 0x00
	PlayChunkBatchReceivedPacketID   = 0x0A
	PlayClientTickEndPacketID        = 0x0C
	PlayClientInformationPacketID    = 0x0D
	PlayKeepAliveServerPacketID      = 0x1B
	PlayPlayerLoadedPacketID         = 0x2B
	PlaySetPlayerPositionPacketID    = 0x1D
	PlaySetPlayerPosRotPacketID      = 0x1E
	PlaySetPlayerRotationPacketID    = 0x1F
	PlaySetPlayerOnGroundPacketID    = 0x20

	// Clientbound
	PlayChunkBatchFinishedPacketID      = 0x0B
	PlayChunkBatchStartPacketID         = 0x0C
	PlayDisconnectPacketID              = 0x20
	PlayGameEventPacketID               = 0x26
	PlayKeepAliveClientPacketID         = 0x2B
	PlayChunkDataPacketID               = 0x2C
	PlayLoginPacketID                   = 0x30
	PlayPlayerInfoUpdatePacketID        = 0x44
	PlaySynchronizePositionPacketID     = 0x46
	PlaySetCenterChunkPacketID          = 0x5C
	PlaySetDefaultSpawnPositionPacketID = 0x5F
	PlaySetTickStatePacketID            = 0x7D
)

Play state packet IDs (protocol 773 / 1.21.10)

View Source
const (
	// MaxPacketSize is the maximum size of an uncompressed packet
	MaxPacketSize = (1 << 21) - 1 // 2097151 bytes (2^21 - 1)

	// MaxCompressedPacketSize is the maximum size of a compressed packet
	MaxCompressedPacketSize = MaxPacketSize

	// MaxServerPacketSize is the maximum size of serverbound packet data
	MaxServerPacketSize = 1 << 23 // 8388608 bytes
)

Variables

This section is empty.

Functions

func NewEncryptedReader

func NewEncryptedReader(r io.Reader, sharedSecret []byte) (io.Reader, error)

NewEncryptedReader wraps a reader with Minecraft AES/CFB8 decryption.

func NewEncryptedWriter

func NewEncryptedWriter(w io.Writer, sharedSecret []byte) (io.Writer, error)

NewEncryptedWriter wraps a writer with Minecraft AES/CFB8 encryption.

func ReadBool

func ReadBool(reader io.Reader) (bool, error)

ReadBool reads a single byte and returns true if 0x01, false if 0x00.

func ReadDouble

func ReadDouble(reader io.Reader) (float64, error)

ReadDouble reads a big-endian float64.

func ReadFloat

func ReadFloat(reader io.Reader) (float32, error)

ReadFloat reads a big-endian float32.

func ReadInt

func ReadInt(reader io.Reader) (int32, error)

ReadInt reads a big-endian int32.

func ReadLong

func ReadLong(reader io.Reader) (int64, error)

ReadLong reads a big-endian int64.

func ReadPosition

func ReadPosition(reader io.Reader) (x, y, z int, err error)

ReadPosition reads a Minecraft block position encoded as int64 (x:26, z:26, y:12).

func ReadPrefixedBytes

func ReadPrefixedBytes(reader io.Reader) ([]byte, error)

ReadPrefixedBytes reads a VarInt length-prefixed byte slice.

func ReadString

func ReadString(reader io.Reader) (string, error)

ReadString reads a VarInt length-prefixed UTF-8 string.

func RegisterPacket

func RegisterPacket(state ProtocolState, direction PacketDirection, id int32, constructor PacketConstructor)

RegisterPacket registers a packet constructor for a state/direction/id tuple.

func RegisterStateHandler

func RegisterStateHandler(state ProtocolState, handler StateHandler)

RegisterStateHandler registers a handler for a protocol state.

func VarIntDecode

func VarIntDecode(r io.Reader) (int32, error)

VarIntDecode reads a VarInt from a reader

func VarIntDecodeBytes

func VarIntDecodeBytes(data []byte) (int32, int, error)

VarIntDecodeBytes decodes a VarInt from a byte slice and returns the value and bytes read

func VarIntEncode

func VarIntEncode(value int32) []byte

VarInt encodes an integer using Minecraft's VarInt format VarInt can represent values from -2^31 to 2^31 - 1

func VarLongDecode

func VarLongDecode(r io.Reader) (int64, error)

VarLongDecode reads a VarLong from a reader

func VarLongDecodeBytes

func VarLongDecodeBytes(data []byte) (int64, int, error)

VarLongDecodeBytes decodes a VarLong from a byte slice and returns the value and bytes read

func VarLongEncode

func VarLongEncode(value int64) []byte

VarLongEncode encodes a long integer using Minecraft's VarLong format VarLong can represent values from -2^63 to 2^63 - 1

Types

type BasePacket

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

BasePacket provides common functionality for all packets

func NewBasePacket

func NewBasePacket(id int32, direction PacketDirection, state ProtocolState) BasePacket

NewBasePacket creates a new base packet

func (BasePacket) Direction

func (p BasePacket) Direction() PacketDirection

Direction returns the packet direction

func (BasePacket) ID

func (p BasePacket) ID() int32

ID returns the packet ID

func (BasePacket) State

func (p BasePacket) State() ProtocolState

State returns the protocol state

type Builder

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

Builder is a helper for building packet data

func NewBuilder

func NewBuilder() *Builder

NewBuilder creates a new packet data builder

func (*Builder) AppendByte

func (b *Builder) AppendByte(b2 byte) *Builder

WriteByte writes a single byte to the builder

func (*Builder) Bytes

func (b *Builder) Bytes() []byte

Bytes returns the built packet data

func (*Builder) WriteBool

func (b *Builder) WriteBool(value bool) *Builder

WriteBool writes a boolean as a single byte (0x01 / 0x00)

func (*Builder) WriteBytes

func (b *Builder) WriteBytes(data []byte) *Builder

WriteBytes writes raw bytes to the builder.

func (*Builder) WriteDouble

func (b *Builder) WriteDouble(value float64) *Builder

WriteDouble writes a 64-bit double (big endian) to the builder

func (*Builder) WriteFloat

func (b *Builder) WriteFloat(value float32) *Builder

WriteFloat writes a 32-bit float (big endian) to the builder

func (*Builder) WriteInt

func (b *Builder) WriteInt(value int32) *Builder

WriteInt writes a signed 32-bit integer (big endian) to the builder

func (*Builder) WriteLong

func (b *Builder) WriteLong(value int64) *Builder

WriteLong writes a signed 64-bit integer (big endian) to the builder

func (*Builder) WritePosition

func (b *Builder) WritePosition(x, y, z int) *Builder

WritePosition writes a block position encoded as a single int64 (x:26, z:26, y:12)

func (*Builder) WritePrefixedBytes

func (b *Builder) WritePrefixedBytes(data []byte) *Builder

WritePrefixedBytes writes VarInt-length-prefixed bytes

func (*Builder) WriteString

func (b *Builder) WriteString(s string) *Builder

WriteString writes a length-prefixed string (UTF-8)

func (*Builder) WriteUShort

func (b *Builder) WriteUShort(value uint16) *Builder

WriteUShort writes an unsigned 16-bit integer (big endian)

func (*Builder) WriteUUID

func (b *Builder) WriteUUID(uuid [16]byte) *Builder

WriteUUID writes a 128-bit UUID (as two big-endian int64s)

func (*Builder) WriteVarInt

func (b *Builder) WriteVarInt(value int32) *Builder

WriteVarInt writes a VarInt to the builder

func (*Builder) WriteVarLong

func (b *Builder) WriteVarLong(value int64) *Builder

WriteVarLong writes a VarLong to the builder

type ConnectionContext

type ConnectionContext struct {
	Conn   net.Conn
	Reader *PacketReader
	Writer *PacketWriter
	State  ProtocolState
	Done   bool

	Username string
	UUID     [16]byte

	AwaitingEncryptionResponse bool
	VerifyToken                []byte

	ClientLocale               string
	ClientViewDistance         int8
	ClientChatMode             int32
	ClientChatColors           bool
	ClientDisplayedSkinParts   uint8
	ClientMainHand             int32
	ClientTextFilteringEnabled bool
	ClientAllowsServerListing  bool
	ClientParticleStatus       int32

	ClientBrand            string
	ConfigurationBrandSent bool

	ConfigurationPreludeSent       bool
	AwaitingKnownPacksResponse     bool
	AwaitingFinishConfigurationAck bool
	SentKnownPacks                 []KnownPack
	ClientKnownPacks               []KnownPack

	// GameData holds state-specific data (e.g., *game.Player during Play state).
	// Using interface{} to avoid circular imports between packet and game packages.
	GameData interface{}
}

ConnectionContext holds data about a client connection and its protocol state.

func NewConnectionContext

func NewConnectionContext(conn net.Conn) *ConnectionContext

func (*ConnectionContext) Close

func (c *ConnectionContext) Close() error

func (*ConnectionContext) EnableEncryption

func (c *ConnectionContext) EnableEncryption(sharedSecret []byte) error

EnableEncryption enables Minecraft AES/CFB8 encryption for both directions.

func (*ConnectionContext) MarkDone

func (c *ConnectionContext) MarkDone()

MarkDone marks the connection as finished without closing the socket directly.

func (*ConnectionContext) SendPacket

func (c *ConnectionContext) SendPacket(ph PacketHandler) error

SendPacket serializes and sends a packet handler through the active writer.

func (*ConnectionContext) TransitionToState

func (c *ConnectionContext) TransitionToState(state ProtocolState) error

TransitionToState updates the protocol state and calls OnStateEnter on the new handler.

type ConnectionIntent

type ConnectionIntent int

Connection intents for handshake

const (
	IntentStatus   ConnectionIntent = 1
	IntentLogin    ConnectionIntent = 2
	IntentTransfer ConnectionIntent = 3
)

type KnownPack

type KnownPack struct {
	Namespace string
	ID        string
	Version   string
}

KnownPack identifies a data pack using namespace, id and version.

type Packet

type Packet struct {
	ID   int32  // Packet ID
	Data []byte // Packet data
}

Packet represents a Minecraft packet

type PacketConstructor

type PacketConstructor func() PacketHandler

type PacketDirection

type PacketDirection int

PacketDirection indicates the direction of packet flow

const (
	Clientbound PacketDirection = iota // Server -> Client
	Serverbound                        // Client -> Server
)

type PacketHandler

type PacketHandler interface {
	// ID returns the packet ID
	ID() int32

	// Direction returns whether this is a clientbound or serverbound packet
	Direction() PacketDirection

	// State returns the protocol state this packet belongs to
	State() ProtocolState

	// Read reads the packet data from a byte slice
	Read(data []byte) error

	// Write writes the packet data to a byte slice
	Write() ([]byte, error)
}

PacketHandler defines the interface for all Minecraft packets

func CreatePacketHandler

func CreatePacketHandler(state ProtocolState, direction PacketDirection, id int32) (PacketHandler, bool)

CreatePacketHandler creates a new packet instance for the given state/direction/id.

type PacketReader

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

PacketReader handles reading packets from a connection

func NewPacketReader

func NewPacketReader(r io.Reader) *PacketReader

NewPacketReader creates a new packet reader

func (*PacketReader) ReadPacket

func (pr *PacketReader) ReadPacket() (*Packet, error)

ReadPacket reads a packet from the connection

func (*PacketReader) SetCompression

func (pr *PacketReader) SetCompression(threshold int32)

SetCompression enables or disables compression

func (*PacketReader) SetReader

func (pr *PacketReader) SetReader(r io.Reader)

SetReader replaces the underlying reader.

type PacketWriter

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

PacketWriter handles writing packets to a connection. It is safe for concurrent use.

func NewPacketWriter

func NewPacketWriter(w io.Writer) *PacketWriter

NewPacketWriter creates a new packet writer

func (*PacketWriter) SetCompression

func (pw *PacketWriter) SetCompression(threshold int32)

SetCompression enables or disables compression for writer

func (*PacketWriter) SetWriter

func (pw *PacketWriter) SetWriter(w io.Writer)

SetWriter replaces the underlying writer.

func (*PacketWriter) WritePacket

func (pw *PacketWriter) WritePacket(p *Packet) error

WritePacket writes a packet to the connection

type ProtocolState

type ProtocolState int

Protocol states for Minecraft server

const (
	StateHandshaking ProtocolState = iota
	StateStatus
	StateLogin
	StateConfiguration
	StatePlay
)

type StateHandler

type StateHandler interface {
	Handle(ctx *ConnectionContext, packet PacketHandler) error
	// OnStateEnter is called when the connection transitions into this state.
	OnStateEnter(ctx *ConnectionContext) error
}

StateHandler is responsible for processing packets in a specific protocol state.

func GetStateHandler

func GetStateHandler(state ProtocolState) (StateHandler, bool)

GetStateHandler retrieves a registered state handler.

Jump to

Keyboard shortcuts

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