Skip to content

Instantly share code, notes, and snippets.

@tatai
Created July 31, 2019 07:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tatai/57d8a5c707522d75cbb2a10d07f46654 to your computer and use it in GitHub Desktop.
Save tatai/57d8a5c707522d75cbb2a10d07f46654 to your computer and use it in GitHub Desktop.
Euskal Encounter Hack-it 27 (2019). Level 3. Extract minecraft coordinates from protocol and creates an image
package main
import (
"bytes"
"encoding/binary"
// "encoding/hex"
"fmt"
"image"
"image/color"
"image/png"
"io/ioutil"
"math"
"os"
)
type Packet struct {
ID uint64
Data []byte
}
func readPacket(r *bytes.Reader) (*Packet, error) {
l, err := binary.ReadUvarint(r)
if err != nil {
return nil, err
}
buf := make([]byte, l)
if _, err := r.Read(buf); err != nil {
return nil, err
}
pr := bytes.NewReader(buf)
_, err = binary.ReadUvarint(pr)
if err != nil {
return nil, err
}
id, err := binary.ReadUvarint(pr)
if err != nil {
return nil, err
}
packet := &Packet{
ID: id,
Data: make([]byte, pr.Len()),
}
if _, err := pr.Read(packet.Data); err != nil {
return nil, err
}
return packet, nil
}
func readString(data []byte) string {
r := bytes.NewReader(data)
if _, err := binary.ReadUvarint(r); err != nil {
return ""
}
buf := make([]byte, r.Len())
if _, err := r.Read(buf); err != nil {
return ""
}
return string(buf)
}
const ymul = 200.0
const ysub = 4.0
const xzmul = 5.0
const xsub = 925.298677
const zsub = 683.356262
func main() {
file := os.Args[1]
content, err := ioutil.ReadFile(file)
if err != nil {
fmt.Println("Error reading file:", err)
os.Exit(1)
}
r := bytes.NewReader(content)
xmax := 0.0
xmin := 1000000.0
ymax := 0.0
ymin := 1000000.0
zmax := 0.0
zmin := 1000000.0
outImg := image.NewRGBA(image.Rectangle{
Min: image.Point{0, 0},
Max: image.Point{1000, 100},
})
for {
var packet *Packet
packet, err = readPacket(r)
if err != nil {
break
}
//fmt.Printf("%02x\n", packet.ID)
if packet.ID == 0x30 {
//fmt.Println(string(packet.Data[len(packet.Data)-1:]))
//fmt.Println(hex.EncodeToString(packet.Data))
} else if packet.ID == 0x10 {
pr := bytes.NewReader(packet.Data)
xb := make([]byte, 8)
yb := make([]byte, 8)
zb := make([]byte, 8)
if _, err = pr.Read(xb); err != nil {
break
}
if _, err = pr.Read(yb); err != nil {
break
}
if _, err = pr.Read(zb); err != nil {
break
}
var onGround byte
if onGround, err = pr.ReadByte(); err != nil {
break
}
/*
y := math.Float64frombits(binary.BigEndian.Uint64(yb))
if y == 4.0 {
fmt.Println(0)
} else if y == 5.0 {
fmt.Println(1)
}
*/
x := math.Float64frombits(binary.BigEndian.Uint64(xb))
y := math.Float64frombits(binary.BigEndian.Uint64(yb))
z := math.Float64frombits(binary.BigEndian.Uint64(zb))
fmt.Printf("x: %f\n", x)
fmt.Printf("y: %f\n", y)
fmt.Printf("z: %f\n", z)
fmt.Printf("onGround: %d\n", onGround)
yint := uint8(math.Round((y - ysub) * ymul))
colour := color.RGBA{yint, yint, yint, 255}
xint := int(math.Round((x - xsub) * xzmul))
zint := int(math.Round((z - zsub) * xzmul))
outImg.Set(zint, xint, colour)
if x > xmax {
xmax = x
}
if x < xmin {
xmin = x
}
if y > ymax {
ymax = y
}
if y < ymin {
ymin = y
}
if z > zmax {
zmax = z
}
if z < zmin {
zmin = z
}
}
}
fmt.Printf("xmax: %f\nxmin: %f\n", xmax, xmin)
fmt.Printf("ymax: %f\nymin: %f\n", ymax, ymin)
fmt.Printf("zmax: %f\nzmin: %f\n", zmax, zmin)
f, err := os.Create("image.png")
if err != nil {
fmt.Println("error creating image file:", err)
os.Exit(1)
}
if err = png.Encode(f, outImg); err != nil {
fmt.Println("error writing image:", err)
os.Exit(1)
}
fmt.Println(err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment