/
connection.go
114 lines (97 loc) · 2.13 KB
/
connection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package minecraftgo
import (
"bytes"
"crypto/cipher"
"encoding/json"
"fmt"
"net"
"net/http"
)
type Conn struct {
TCP *net.TCPConn
Compressed bool
Encrypted bool
AuthResp APIAuthResponse
Cipher cipher.Stream
CompressionThreshold int
}
func Connect(ip *net.TCPAddr, username string, email string, password string) (*Conn, error) {
// Authenticate the user with Mojang
resp, err := http.Post("https://authserver.mojang.com/authenticate", "application/json", bytes.NewBufferString(`
{
"agent": {
"name": "Minecraft",
"version": 1
},
"username": "`+email+`",
"password": "`+password+`",
"requestUser": true
}
`))
if err != nil {
panic(err)
}
defer resp.Body.Close()
var authResp APIAuthResponse
j := json.NewDecoder(resp.Body)
j.Decode(&authResp)
c := new(Conn)
c.AuthResp = authResp
c.TCP, err = net.DialTCP("tcp", nil, ip)
if err != nil {
return nil, err
}
go c.Listener()
// Send handshake (state=2)
p := Marshal(Handshake{
Version: 340,
Address: String(ip.IP.String() + "\x00FML\x00"), // Not used
Port: uint16(ip.Port), // Not used
Next: 2,
})
c.TCP.Write(Marshal(UncompressedPacket{
PacketID: 0,
Length: VarInt(len(p)),
}))
c.TCP.Write(p)
// Send Login Start
p = Marshal(LoginStart{
Username: String(username),
})
c.TCP.Write(Marshal(UncompressedPacket{
PacketID: 0,
Length: VarInt(len(p)),
}))
c.TCP.Write(p)
fmt.Println("sent login request")
return c, nil
}
func Ping(ip *net.TCPAddr) ([]byte, error) {
c := new(Conn)
var err error
c.TCP, err = net.DialTCP("tcp", nil, ip)
if err != nil {
return []byte{}, err
}
// Send handshake (state=1)
p := Handshake{
Version: 340,
Address: "", // Not used
Port: 25565, // Not used
Next: 1,
}
c.TCP.Write(Marshal(UncompressedPacket{
PacketID: 0,
}))
c.TCP.Write(Marshal(p))
// Send request
c.TCP.Write(Marshal(UncompressedPacket{
PacketID: 0,
}))
// Used to get initial length of packet
var q UncompressedPacket
Unmarshal(c.TCP, &q)
var out String
Unmarshal(c.TCP, &out)
return []byte(out), nil
}