-
Notifications
You must be signed in to change notification settings - Fork 18
/
packet.go
197 lines (162 loc) · 4.17 KB
/
packet.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
package mc
import (
"bufio"
"bytes"
"errors"
"fmt"
"io"
)
var (
ErrInvalidPacketID = errors.New("invalid packet id")
ErrPacketTooBig = errors.New("packet contains too much data")
MaxPacketSize = 2097151
)
const (
ServerBoundHandshakePacketID byte = 0x00
HandshakePacketID int = 0x00
StatusState = 1
LoginState = 2
HandshakeStatusState = VarInt(StatusState)
HandshakeLoginState = VarInt(LoginState)
ForgeSeparator = "\x00"
RealIPSeparator = "///"
)
// Packet is the raw representation of message that is send between the client and the server
type Packet struct {
ID byte
Data []byte
}
type McPacket interface {
MarshalPacket() Packet
}
// Scan decodes and copies the Packet data into the fields
func (pk Packet) Scan(fields ...FieldDecoder) error {
return ScanFields(bytes.NewReader(pk.Data), fields...)
}
// Marshal encodes the packet and all it's fields
func (pk *Packet) Marshal() []byte {
var packedData []byte
data := []byte{pk.ID}
data = append(data, pk.Data...)
packetLength := VarInt(int32(len(data))).Encode()
packedData = append(packedData, packetLength...)
return append(packedData, data...)
}
// ScanFields decodes a byte stream into fields
func ScanFields(r DecodeReader, fields ...FieldDecoder) error {
for _, field := range fields {
if err := field.Decode(r); err != nil {
return err
}
}
return nil
}
// MarshalPacket transforms an ID and Fields into a Packet
func MarshalPacket(ID byte, fields ...FieldEncoder) Packet {
var pkt Packet
pkt.ID = ID
for _, v := range fields {
pkt.Data = append(pkt.Data, v.Encode()...)
}
return pkt
}
// ReadPacketBytes decodes a byte stream and cuts the first Packet as a byte array out
func ReadPacketBytes(r DecodeReader) ([]byte, error) {
var packetLength VarInt
if err := packetLength.Decode(r); err != nil {
return nil, err
}
if packetLength < 1 {
return nil, fmt.Errorf("packet length too short")
}
data := make([]byte, packetLength)
if _, err := io.ReadFull(r, data); err != nil {
return nil, fmt.Errorf("reading the content of the packet failed: %v", err)
}
return data, nil
}
// ReadPacketOld decodes and decompresses a byte stream and cuts the first Packet out
func ReadPacketOld(r DecodeReader) (Packet, error) {
data, err := ReadPacketBytes(r)
if err != nil {
return Packet{}, err
}
return Packet{
ID: data[0],
Data: data[1:],
}, nil
}
func ReadPacket(r DecodeReader) (Packet, error) {
packetLength, err := ReadVarInt(r)
if err != nil {
return Packet{}, err
}
if packetLength < 1 {
return Packet{}, fmt.Errorf("packet length too short")
}
data := make([]byte, packetLength)
if _, err := io.ReadFull(r, data); err != nil {
return Packet{}, fmt.Errorf("reading the content of the packet failed: %v", err)
}
return Packet{
ID: data[0],
Data: data[1:],
}, nil
}
func ReadPacket_WithBytes(b []byte) (Packet, error) {
buf := bytes.NewBuffer(b)
reader := bufio.NewReader(buf)
return ReadPacket3(reader)
}
func ReadPacket3(r *bufio.Reader) (Packet, error) {
packetLength, err := ReadVarInt_ByteReader(r)
if err != nil {
return Packet{}, err
}
if packetLength < 1 {
return Packet{}, fmt.Errorf("packet length too short")
}
data := make([]byte, packetLength)
if _, err := io.ReadFull(r, data); err != nil {
return Packet{}, fmt.Errorf("reading the content of the packet failed: %v", err)
}
return Packet{
ID: data[0],
Data: data[1:],
}, nil
}
func ReadPacket3_Handshake(r *bufio.Reader) (ServerBoundHandshake, error) {
var hs ServerBoundHandshake
packetLength, err := ReadVarInt_ByteReader(r)
if err != nil {
return hs, err
}
if packetLength < 1 {
return hs, fmt.Errorf("packet length too short")
}
packetID, err := ReadVarInt_ByteReader(r)
if err != nil {
return hs, err
}
if packetID != HandshakePacketID {
return hs, ErrInvalidPacketID
}
hs.ProtocolVersion, err = ReadVarInt_ByteReader(r)
if err != nil {
return hs, err
}
hs.ServerAddress, err = ReadString_ByteReader(r)
if err != nil {
return hs, err
}
hs.ServerPort, err = ReadShot_ByteReader(r)
if err != nil {
return hs, err
}
state, err := ReadVarInt_ByteReader(r)
if err != nil {
return hs, err
}
hs.NextState = byte(state)
return hs, nil
}