⛏ 🐹 Minecraft Protocol implementation in Go

Go Reference
illustration by @talentlessguy

Install

Go 1.16.x is required to use this library

go get github.com/BRA1L0R/go-mcproto

Opening a connection

client := mcproto.Client{Host: "IP or Hostname", Port: 25565, Name: "GoBot", ProtocolVersion: 754}

Before opening a connection to a server, you'll have to specify some vital information such as the host, the port, the name of your bot (which will login in offline mode) and the protocol version, which will have to match the server one, unless the server uses some kind of backward compatibility plugin such as ViaVersion.

In this case, 754 is the protocol version for Minecraft 1.16.5 but you can find all the versions here

Once you define client, you can either use the already implemented handshake method (client.Initialize) or you can manually open the connection using client.Connect

client.Initialize only supports offline mode (unauthenticated SP) at the moment but I will soon implement online mode as well.

Defining a packet

Not all packets are implemented in the library there are only the ones that will get you past the login state.

Fortunately, defining a packet with go-mcproto is as easy as declaring a struct. Here's a quick example

type ChatMessage struct {
  packets.MinecraftPacket

  JsonData string `mc:"string"`
  Position byte   `mc:"inherit"`
  Sender   []byte `mc:"bytes" len:"16"` // UUID is 128bit, hence the 16 byte len
}

packets.MinecraftPackets will add the rest of the fields which are needed for a packet to be conformant to the standard format, compressed or not

ChatMessage will also inherit from packets.MinecraftPackets the methods for serialization of the fields into Data and the final serialization which returns the byte slice that can be sent over a connection using client.WritePacket

Arrays

Sometimes you might encounter a packet that sends before an array the length of it. Fortunately, you can still deserialize the packet with no extra steps thanks to the len tag:

type Biome struct {
  BiomeID int32 `mc:"varint"`
}

type ChunkData struct {
  packets.MinecraftPacket

  BiomesLength int32   `mc:"varint"`
  Biomes       []Biome `mc:"array" len:"BiomesLength"`
}

The Biome struct can contain as many fields as you like, as the minecraft protocol has a lot of cases where there are multi-fielded arrays

Field Dependency

In some cases, a field is present only if the previous one is true (in the case of a boolean). You can still manage to do this with only struct tags by using the depends_on tag:

type PlayerInfo struct {
  packets.MinecraftPacket

  HasDisplayName bool   `mc:"inherit"`
  DisplayName    string `mc:"string" depends_on:"HasDisplayName"`
}

All the available tags

This library already integrates all the possible types to define all possible data types, including NBTs.

Here's a list of all the available tags:

  • mc:"inherit": this tag covers all integers, complexes, floats, and the byte type. It inherits the length from the type defined in the struct. See the examples above. Please note: the Minecraft protocol is effectively big-endian, except varints, which are defined using another tag.
  • mc:"varint" and mc:"varlong": Used to encode varints and varlongs respectively. Requires a int32 and int64 (respectively) as the field types
  • mc:"string": requires a string field type in the struct, it encodes its length using a varint end then the string is encoded using the UTF-8.
  • mc:"bytes" len:"X": Reads X bytes from the buffer and puts it in a byte slice, which must be the type of the struct field this tag is assigned to. X is only required for deserialization in this case
  • mc:"ignore" len:"X": Ignores X bytes from the buffer. This means that it discards X bytes from the data buffer in case of deserialization or writes X null bytes in the data buffer in case of serialization
  • mc:"nbt": Encodes or decodes an nbt struct. For more information check https://github.com/Tnze/go-mc/tree/master/nbt
  • mc:"array" len:"X": Can be used to array every previous tags. Check this section

Sending a packet

Once you have defined a packet you want to send, you will have to call client.WritePacket() to serialize the data and send it over a connection.

packet := new(MyPacket)
packet.PacketID = 0x00
// you can look up the packet ids on wiki.vg
// all the other fields

client.WritePacket(packet)

Sending a raw packet

If you already put data into the Data buffer by yourself, without using the included serialized, then you can send the packet using the WriteRawPacket method.

Receiving a packet

Receiving a packet is done by calling client.ReceivePacket. The server will receive the packet length and wait for the server until all bytes are fulfilled. If it encounters an error it will return it, but it will keep receiving packets as all the packet length is already consumed from the connection.

client.ReceivePacket will return a MinecraftPacket, which can be deserialized using the DeserializeData method. It'a called by passing a pointer to a struct containing mc struct tags, as explained here

packet, err := client.ReceivePacket()
if err != nil {
  // an error has been encountered during the reception of the packet
  panic(err)
}

keepalive := new(models.KeepAlivePacket)
err := packet.DeserializeData(keepalive)
if err != nil {
  panic(err)
}

fmt.Println(keepalive.KeepAliveID) // 123456

Variable packet content

There are multiple cases in the Minecraft protocol where the packet content is variable depending on certain values inside the struct. This is no problem for the library, as you can easily receive a part of the packet (by defining only the fixed fields in the struct) and then, later on, continue the deserialization by calling DeserializeData on a different struct.

Here's a practical demonstration:

type FixedContent struct {
  packets.MinecraftPacket

  PacketType int32 `mc:"varint"`
}

type SomeOtherContent struct {
  packets.MinecraftPacket

  Data string `mc:"string"`
}

packet, _ := client.ReceivePacket()
// from now on I'm gonna avoid doing error handling in the examples for practical reasons
// but you MUST do it.

fixedPacket := new(FixedContent)
packet.DeserializeData(fixedPacket)

if fixedPacket.PacketType == 0x05 {
  someOtherContent := new(SomeOtherContent)
  packet.DeserializeData(someOtherContent)
} else {
  panic("Unknown packet type!")
}

Example

This example initializes the connection between the client and a server, thus switching to the Play state, and listens for keepalive packets to which it responds

package main

import (
	"github.com/BRA1L0R/go-mcproto"
	"github.com/BRA1L0R/go-mcproto/packets/models"
)

func main() {
  client := mcproto.Client{
    Host: "my.minecraftserver.com",
    Port: 25565,
    ProtocolVersion: 754, // 1.16.5
    Name: "ExampleBot",
  }

  client.Initialize()

  for {
    packet, err := client.ReceivePacket()
    if err != nil {
      panic(err)
    }

    if packet.PacketID == 0x1F { // clientbound keepalive packetid
      receivedKeepalive := new(models.KeepAlivePacket)
      err := packet.DeserializeData(receivedKeepalive)
      if err != nil {
        panic(err)
      }

      serverBoundKeepalive := new(models.KeepAlivePacket)
      serverBoundKeepalive.KeepAliveID = receivedKeepalive.KeepAliveID
      serverBoundKeepalive.PacketID = 0x10 // serverbound keepaliveid

      err = client.WritePacket(serverBoundKeepalive)
    }
  }
}
Owner
Pietro Tamilia
@stack_smash on telegram.
Pietro Tamilia
Similar Resources

An open-source re-implementation of Pokémon Red

An open-source re-implementation of Pokémon Red

This project is open source re-implementation of Pokémon Red.

Dec 6, 2022

This project is designed to be an open source implementation for streaming desktop games using WebRTC

This project is designed to be an open source implementation for streaming desktop games using WebRTC

The aim of this project is develop a WebRTC screenshare designed for streaming video games and accepting remote inputs. There will be ansible instruct

Oct 6, 2022

A go implementation of Conway's game of life

go-life A go implementation of Conway's game of life. The program takes input from stdin. It's recommended to use it as cat input.txt | go-life with i

Oct 20, 2021

Go implementation of 2048 game

Go implementation of 2048 game

Oct 21, 2021

snake game implementation using 2d array in Go

snake game implementation using 2d array in Go

Snake Game Implementation Snake game implementation in Go using a 2-dimensional array. Demo Install download the package git clone https://github.com/

May 14, 2022

a Go implementation of the game of Briscola

BrisGolang BrisGolang is a Go implementation of the game of briscola using the WebSocket protocol for client/server communication. Usage You can play

Sep 15, 2022

Implementation of a popular graphics benchmark written on Ebiten.

Implementation of a popular graphics benchmark written on Ebiten.

Ebiten Bunny Mark This is an implementation of the popular graphics benchmark written on Ebiten. The initial benchmark was created by Ian Lobb (code)

Dec 7, 2022

An implementation of Conway's Game of Life.

An implementation of Conway's Game of Life.

Conway's Game of Life From Wikipedia, the free encyclopedia: The Game of Life, also known simply as Life, is a cellular automaton devised by the Briti

Mar 16, 2022

mcstatusgo is a pure Go Minecraft service status checker for Java edition Minecraft servers

mcstatusgo is a pure Go Minecraft service status checker for Java edition Minecraft servers. mcstatusgo supports requesting information through the status and query protocols.

Aug 12, 2022

⛏ 🐹 Minecraft Protocol implementation in Go

⛏ 🐹 Minecraft Protocol implementation in Go

illustration by @talentlessguy Install Go 1.16.x is required to use this library go get github.com/BRA1L0R/go-mcproto Opening a connection client := m

Sep 20, 2022

This utility allows you to execute Minecraft server commands through the RCON protocol via Telegram chat.

Minecraft RCON by Telegram This utility allows you to execute Minecraft server commands through the RCON protocol via Telegram chat. FAQ When you run

Jul 24, 2022

Go language implementation of a blockchain based on the BDLS BFT protocol. The implementation was adapted from Ethereum and Sperax implementation

BDLS protocol based PoS Blockchain Most functionalities of this client is similar to the Ethereum golang implementation. If you do not find your quest

Oct 14, 2022

Minecraft server implementation using Golang

Deepslate Deepslate is a Minecraft server implementation in Go. Deepslate if WIP and currently not available for installation Goals First implementati

Nov 19, 2021

Implementation of Minecraft protocols : ping, query and icon.

Implementation of Minecraft protocols : ping, query and icon.

mcutils - Implementation of Minecraft protocols in Go Informations General All protocols are implemented in Go, without any external dependency. All p

Dec 19, 2022

wire protocol for multiplexing connections or streams into a single connection, based on a subset of the SSH Connection Protocol

qmux qmux is a wire protocol for multiplexing connections or streams into a single connection. It is based on the SSH Connection Protocol, which is th

Dec 26, 2022

Eunomia is a distributed application framework that support Gossip protocol, QuorumNWR algorithm, PBFT algorithm, PoW algorithm, and ZAB protocol and so on.

Introduction Eunomia is a distributed application framework that facilitates developers to quickly develop distributed applications and supports distr

Sep 28, 2021

A simple tool to convert socket5 proxy protocol to http proxy protocol

Socket5 to HTTP 这是一个超简单的 Socket5 代理转换成 HTTP 代理的小工具。 如何安装? Golang 用户 # Required Go 1.17+ go install github.com/mritd/s2h@master Docker 用户 docker pull m

Jan 2, 2023

A project outputs Bluetooth Low Energy (BLE) sensors data in InfluxDB line protocol formatA project outputs Bluetooth Low Energy (BLE) sensors data in InfluxDB line protocol format

Intro This project outputs Bluetooth Low Energy (BLE) sensors data in InfluxDB line protocol format. It integrates nicely with the Telegraf execd inpu

Apr 15, 2022

Create a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compileCreate a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compile

Interview Assignment Overview You assignment is to create a Protocol Buffers (Protobuf) plugin, which is executed with the protoc compiler. In this ex

Nov 19, 2021
Minecraft server implementation using Golang

Deepslate Deepslate is a Minecraft server implementation in Go. Deepslate if WIP and currently not available for installation Goals First implementati

Nov 19, 2021
Go Minecraft Client
Go Minecraft Client

Steven Not actively maintained anymore A work in progress Minecraft client in Go. Don't expect it to go anywhere, just doing this for fun. Images Buil

Dec 23, 2022
Minecraft server made in go, faster and better!

ElytraGo Minecraft server made in go, faster and better! Project is in early stage, but I'm trying continuously update it with new lines of code :)) L

Dec 9, 2022
Regolith is an Addon Compiler for the Bedrock Edition of Minecraft.

Much like bridge v2, Regolith introduces the concept of a "project folder", where your addons are written, including the RP, the BP, and any models, textures or configuration files. This single-folder-structure is great for version control, and allows you to keep your "source-of-truth" outside of com.mojang.

Nov 13, 2022
Quick and dirty Minecraft player head to SVG converter

Head SVG Quick and dirty Minecraft player head to SVG converter. Can be used to generate player head icons. Usage usage: Head SVG [-h|--help] -n|--nam

May 29, 2022
Minecraft Bedrock Edition server software written in Go
Minecraft Bedrock Edition server software written in Go

Dragonfly Dragonfly is a heavily asynchronous server software for Minecraft Bedrock Edition written in Go.

Jan 3, 2023
Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol.
 Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol.

Simple Matchmaking Simple rule based matchmaking for your online game with support of Redcon(RESP) protocol. 1- Simple Match Rule Easiest usage of sys

Jan 4, 2023
Go implementation of the A* search algorithm

go-astar A* pathfinding implementation for Go The A* pathfinding algorithm is a pathfinding algorithm noted for its performance and accuracy and is co

Dec 29, 2022
An implementation of the popular game Codenames created with Go and React.

OpenCodenames A real-time implementation of Codenames created with React/TypeScript and Golang. You can play the game here! Installation Stack: React

Aug 8, 2021
An open source re-implementation of Diablo 2
An open source re-implementation of Diablo 2

OpenDiablo2 Join us on Discord! Development Live stream Support us on Patreon We are also working on a toolset: https://github.com/OpenDiablo2/HellSpa

Jan 8, 2023