Skip to content

Commit 15e10e9

Browse files
committed
[wip] Update Join Game packet
1 parent 31b9302 commit 15e10e9

11 files changed

+160
-109
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ require (
66
github.com/dave/jennifer v1.4.1
77
github.com/google/uuid v1.1.1
88
github.com/stretchr/testify v1.7.0
9+
github.com/yuin/stagparser v0.0.0-20181218160030-e10a81132760
910
golang.org/x/tools v0.1.0
1011
)

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
1010
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
1111
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1212
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
13+
github.com/yuin/stagparser v0.0.0-20181218160030-e10a81132760 h1:i+m5+M2renk/OmDHvzRjlBQXm+5X6WR6xPjWfHNzvcM=
14+
github.com/yuin/stagparser v0.0.0-20181218160030-e10a81132760/go.mod h1:+qbo7cNcx8dT/77C41x4MZbasDrLuUDI/04ZGR/7IqM=
1315
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
1416
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
1517
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=

packet/client_settings.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
const ClientSettingsPacketID int32 = 0x05
1111

1212
type ClientSettingsPacket struct {
13-
Lang enc.String
13+
Locale enc.String `pkt:"strLen(16)"`
1414
ViewDistance enc.Byte
1515
ChatVisibility enc.VarInt
1616
EnableChatColors enc.Bool

packet/client_settings_gen.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packet/handshake.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const HandshakePacketID int32 = 0x00
1212
// https://wiki.vg/Protocol#Handshake
1313
type HandshakePacket struct {
1414
ProtoVer enc.VarInt
15-
ServerAddr enc.String
15+
ServerAddr enc.String `pkt:"strLen(255)"`
1616
ServerPort enc.UnsignedShort
1717
NextState types.ConnectionState
1818
}

packet/join_game.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@ import (
55
"github.com/Raqbit/mcproto/types"
66
)
77

8-
//go:generate go run ../tools/genpacket/genpacket.go -packet=JoinGamePacket -output=join_game_gen.go
8+
//go:generate go run ../tools/genpacket -packet=JoinGamePacket -output=join_game_gen.go
99

1010
const JoinGamePacketID int32 = 0x26
1111

1212
type JoinGamePacket struct {
13-
PlayerID enc.Int
14-
GameMode enc.UnsignedByte
15-
Dimension enc.Int
13+
PlayerID enc.Int
14+
IsHardcore enc.Bool
15+
GameMode enc.UnsignedByte
16+
PreviousGameMode enc.Byte
17+
WorldCount enc.VarInt
18+
WorldNames []types.Identifier `pkt:"lenFrom(WorldCount)"`
19+
//DimensionCodec nbt.Something // TODO
20+
//Dimension nbt.Something // TODO
21+
WorldName types.Identifier
1622
HashedSeed enc.Long
1723
MaxPlayers enc.UnsignedByte
18-
LevelType enc.String `len:"16"`
1924
ViewDistance enc.VarInt
20-
ReducedDebug enc.Bool
25+
ReducedDebugInfo enc.Bool
2126
EnableRespawnScreen enc.Bool
27+
IsDebug enc.Bool
28+
IsFlat enc.Bool
2229
}
2330

2431
func (*JoinGamePacket) String() string {

packet/join_game_gen.go

-68
This file was deleted.

packet/login_start.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const LoginStartPacketID int32 = 0x00
1111

1212
// https://wiki.vg/Protocol#Login_Start
1313
type LoginStartPacket struct {
14-
Name enc.String
14+
Name enc.String `pkt:"strLen(16)"`
1515
}
1616

1717
func (*LoginStartPacket) Info() PacketInfo {

packet/login_success.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const LoginSuccessPacketID = 0x02
1212
// https://wiki.vg/Protocol#Login_Success
1313
type LoginSuccessPacket struct {
1414
UUID enc.UUID
15-
Username enc.String
15+
Username enc.String `pkt:"strLen(16)"`
1616
}
1717

1818
func (*LoginSuccessPacket) Info() PacketInfo {

tools/genpacket/genpacket.go

+60-29
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const (
2020
WriterName = "w"
2121
ReaderName = "r"
2222
Directory = "."
23+
SliceItemName = "v"
2324
)
2425

2526
var (
@@ -124,14 +125,19 @@ func (g *Generator) generate(typeName string) error {
124125
return fmt.Errorf("%s is not a struct type", typeName)
125126
}
126127

127-
name := obj.Name()
128-
idName := strings.ToLower(name[:1])
128+
receiverName := strings.ToLower(typeName[:1])
129+
130+
//_, err := parsePacket(struc, typeName)
131+
132+
//if err != nil {
133+
// return fmt.Errorf("could not parse packet struct %s: %w", typeName, err)
134+
//}
129135

130136
g.file.
131137
Func().
132138
Params(
133-
jen.Id(idName).
134-
Id("*" + obj.Name()),
139+
jen.Id(receiverName).
140+
Id("*" + typeName),
135141
).
136142
Id(FuncMarshal).
137143
Params(jen.Id(WriterName).Qual("io", "Writer")).
@@ -143,18 +149,13 @@ func (g *Generator) generate(typeName string) error {
143149

144150
for i := 0; i < struc.NumFields(); i++ {
145151
field := struc.Field(i)
152+
_, isSlice := field.Type().(*types.Slice)
146153

147-
group.If(
148-
jen.Err().
149-
Op("=").
150-
Id(idName).
151-
Dot(field.Name()).
152-
Dot("Write").
153-
Call(
154-
jen.Id(WriterName),
155-
),
156-
jen.Err().Op("!=").Nil(),
157-
).Block(jen.Return().Err())
154+
if isSlice {
155+
genSliceFieldWrite(group, receiverName, field)
156+
} else {
157+
genFieldWrite(group, receiverName, field)
158+
}
158159
}
159160

160161
group.Return().Nil()
@@ -163,7 +164,7 @@ func (g *Generator) generate(typeName string) error {
163164
g.file.
164165
Func().
165166
Params(
166-
jen.Id(idName).
167+
jen.Id(receiverName).
167168
Id("*" + obj.Name()),
168169
).
169170
Id(FuncUnmarshal).
@@ -177,17 +178,7 @@ func (g *Generator) generate(typeName string) error {
177178
for i := 0; i < struc.NumFields(); i++ {
178179
field := struc.Field(i)
179180

180-
group.If(
181-
jen.Err().
182-
Op("=").
183-
Id(idName).
184-
Dot(field.Name()).
185-
Dot("Read").
186-
Call(
187-
jen.Id(ReaderName),
188-
),
189-
jen.Err().Op("!=").Nil(),
190-
).Block(jen.Return().Err())
181+
genFieldRead(group, receiverName, field)
191182
}
192183

193184
group.Return().Nil()
@@ -196,6 +187,46 @@ func (g *Generator) generate(typeName string) error {
196187
return nil
197188
}
198189

199-
func unqualified(*types.Package) string {
200-
return ""
190+
func genSliceFieldWrite(group *jen.Group, receiverName string, field *types.Var) {
191+
group.For(jen.List(jen.Id("_"), jen.Id(SliceItemName)).
192+
Op(":=").
193+
Range().
194+
Id(receiverName).
195+
Dot(field.Name()).
196+
BlockFunc(func(group *jen.Group) {
197+
group.If(jen.Err().Op("=").Id(SliceItemName).Dot("Write").
198+
Call(
199+
jen.Id(WriterName),
200+
),
201+
jen.Err().Op("!=").Nil(),
202+
).Block(jen.Return().Err())
203+
}))
204+
}
205+
206+
func genFieldWrite(group *jen.Group, receiverName string, field *types.Var) {
207+
group.If(
208+
jen.Err().
209+
Op("=").
210+
Id(receiverName).
211+
Dot(field.Name()).
212+
Dot("Write").
213+
Call(
214+
jen.Id(WriterName),
215+
),
216+
jen.Err().Op("!=").Nil(),
217+
).Block(jen.Return().Err())
218+
}
219+
220+
func genFieldRead(group *jen.Group, receiverName string, field *types.Var) {
221+
group.If(
222+
jen.Err().
223+
Op("=").
224+
Id(receiverName).
225+
Dot(field.Name()).
226+
Dot("Read").
227+
Call(
228+
jen.Id(ReaderName),
229+
),
230+
jen.Err().Op("!=").Nil(),
231+
).Block(jen.Return().Err())
201232
}

tools/genpacket/packet.go

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/yuin/stagparser"
6+
"go/types"
7+
"strings"
8+
)
9+
10+
type param struct {
11+
name string
12+
value interface{}
13+
}
14+
15+
type field struct {
16+
name string
17+
params []param
18+
}
19+
20+
type packet struct {
21+
name string
22+
fields []field
23+
}
24+
25+
func (p *packet) String() string {
26+
sb := strings.Builder{}
27+
sb.WriteString(fmt.Sprintf("packet %s {\n", p.name))
28+
for _, fld := range p.fields {
29+
sb.WriteString(fmt.Sprintf("\t%s (", fld.name))
30+
for _, prm := range fld.params {
31+
sb.WriteString(fmt.Sprintf("%s=%s,", prm.name, prm.value))
32+
}
33+
sb.WriteString(")")
34+
}
35+
sb.WriteString("}\n")
36+
37+
return sb.String()
38+
}
39+
40+
func parsePacket(packetType *types.Struct, structName string) (packet, error) {
41+
fields := make([]field, packetType.NumFields())
42+
43+
for i := 0; i < packetType.NumFields(); i++ {
44+
f := packetType.Field(i)
45+
t := packetType.Tag(i)
46+
47+
// TODO: stagparser expects us to give it one "value" of a struct tag (`key:"value"`)
48+
// TODO: this is hard to do as the parser for it is only really present in reflect, not AST.
49+
// TODO: a custom tag parser will probably have to be implemented
50+
defs, err := stagparser.ParseTag(t, structName)
51+
52+
if err != nil {
53+
return packet{}, fmt.Errorf("could not parse struct tag for field %s: %w", f.Name(), err)
54+
}
55+
56+
params := make([]param, len(defs))
57+
58+
for j, def := range defs {
59+
for name, value := range def.Attributes() {
60+
params[j] = param{
61+
name: name,
62+
value: value,
63+
}
64+
}
65+
}
66+
67+
fields[i] = field{
68+
name: f.Name(),
69+
params: make([]param, 0),
70+
}
71+
72+
}
73+
74+
return packet{
75+
name: structName,
76+
fields: fields,
77+
}, nil
78+
}

0 commit comments

Comments
 (0)