package main
import (
"fmt"
"encoding/binary"
"net"
"github.com/kr/pretty"
"io/ioutil"
)
type Initializer struct {
Host string
Port int
}
func main() {
fmt.Println("Hello world")
init := Initializer{"212.114.60.140", 25565}
data, err := GetData(init)
if err != nil {
fmt.Println(err)
}
pretty.Println(data)
}
func pack_data(data []byte) []byte {
length := len(data)
var bs = make([]byte, 2)
binary.BigEndian.PutUint16(bs, uint16(length))
newData := pack_variant(data)
return append(bs, newData...)
}
func pack_uint32(i int) []byte {
bs := make([]byte, 4)
binary.BigEndian.PutUint32(bs, uint32(i))
return bs
}
func pack_port(port int) []byte {
var bs = make([]byte, 2)
binary.BigEndian.PutUint16(bs, uint16(port))
return bs
}
func pack_variant(d []byte) []byte {
var bs = make([]byte, 2)
var o []byte
for i := range(d){
b := d[i] & 0x7F
d[i] >>= 7
if d[i] > 0 {
binary.BigEndian.PutUint16(bs, uint16(b) | 0x80)
} else {
bs[0] = 0
}
o = append(o, bs...)
}
return o
}
func GetData(initializer Initializer) (interface{}, error) {
// Minecraft Server Handshake
// Two requests should be made
// first: 0x00 Packet ID + -1 as Protocol Version (VarInt) + ServerAddress as String + ServerPort as Unsigned Short, Next State should be 1 VarInt in this case
// second: 0x00
hostport := append([]byte(initializer.Host), pack_port(initializer.Port)...)
hostport = append(hostport, 0x01)
hostport = pack_data(hostport)
first := []byte {0x00, 0x00}
first = append(first, pack_data(hostport)...)
second := []byte {0x00}
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", initializer.Host, initializer.Port))
if err != nil {
return nil, err
}
defer conn.Close()
_, err = conn.Write(pack_data(first))
if err != nil {
return nil, err
}
_, err = conn.Write(pack_data(second))
if err != nil {
return nil, err
}
//var buf bytes.Buffer
//io.Copy(&buf, conn)
buf, err := ioutil.ReadAll(conn)
pretty.Println(buf)
//unpack_variant(conn) // Packet length
//unpack_variant(conn) // Packet ID
//ret, err := unpack_variant(conn) // String length
//if err != nil {
// return nil, err
//}
//
//var d []byte
//for len(d) < int(ret) {
// data := make([]byte, 1024)
// _, err := conn.Read(data)
// if err != nil {
// return nil, err
// }
//
// d = append(d, data...)
//}
//returner, err := json.Marshal(&buf)
return buf, err
}
Comments