Skip to content

Commit 56fdee2

Browse files
dragonfly/server: Update for 1.21.60
1 parent bae2538 commit 56fdee2

22 files changed

+247
-111
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/go-gl/mathgl v1.2.0
1111
github.com/google/uuid v1.6.0
1212
github.com/pelletier/go-toml v1.9.5
13-
github.com/sandertv/gophertunnel v1.43.1
13+
github.com/sandertv/gophertunnel v1.43.2-0.20250205122318-98ae443c59fd
1414
github.com/segmentio/fasthash v1.0.3
1515
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329
1616
golang.org/x/mod v0.22.0

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
3939
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
4040
github.com/sandertv/go-raknet v1.14.2 h1:UZLyHn5yQU2Dq2GVq/LlxwAUikaq4q4AA1rl/Pf3AXQ=
4141
github.com/sandertv/go-raknet v1.14.2/go.mod h1:/yysjwfCXm2+2OY8mBazLzcxJ3irnylKCyG3FLgUPVU=
42-
github.com/sandertv/gophertunnel v1.43.1 h1:wY6Fy8dRMKtpZUQzCR35o9k05135vOJZhrz0GF6OXFI=
43-
github.com/sandertv/gophertunnel v1.43.1/go.mod h1:XuEJo+ARim+NKiD90Z56sQRcDtCOErz26e2bt3LEd9I=
42+
github.com/sandertv/gophertunnel v1.43.2-0.20250205122318-98ae443c59fd h1:uLUw6XKdxx2gg0+USWUQQ98RJnRZqxrS4IQnt2wmK/g=
43+
github.com/sandertv/gophertunnel v1.43.2-0.20250205122318-98ae443c59fd/go.mod h1:XuEJo+ARim+NKiD90Z56sQRcDtCOErz26e2bt3LEd9I=
4444
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
4545
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
4646
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=

server/block/copper_door.go

+1-8
Original file line numberDiff line numberDiff line change
@@ -178,21 +178,14 @@ func (d CopperDoor) EncodeItem() (name string, meta int16) {
178178

179179
// EncodeBlock ...
180180
func (d CopperDoor) EncodeBlock() (name string, properties map[string]any) {
181-
direction := d.Facing
182-
if d.Facing == cube.East {
183-
direction = cube.North
184-
} else if d.Facing == cube.North {
185-
direction = cube.East
186-
}
187-
188181
name = "copper_door"
189182
if d.Oxidation != UnoxidisedOxidation() {
190183
name = d.Oxidation.String() + "_" + name
191184
}
192185
if d.Waxed {
193186
name = "waxed_" + name
194187
}
195-
return "minecraft:" + name, map[string]any{"direction": int32(direction), "door_hinge_bit": d.Right, "open_bit": d.Open, "upper_block_bit": d.Top}
188+
return "minecraft:" + name, map[string]any{"minecraft:cardinal_direction": d.Facing.String(), "door_hinge_bit": d.Right, "open_bit": d.Open, "upper_block_bit": d.Top}
196189
}
197190

198191
// allCopperDoors returns a list of all copper door types

server/block/wood_door.go

+2-12
Original file line numberDiff line numberDiff line change
@@ -137,20 +137,10 @@ func (d WoodDoor) EncodeItem() (name string, meta int16) {
137137

138138
// EncodeBlock ...
139139
func (d WoodDoor) EncodeBlock() (name string, properties map[string]any) {
140-
direction := 3
141-
switch d.Facing {
142-
case cube.South:
143-
direction = 1
144-
case cube.West:
145-
direction = 2
146-
case cube.East:
147-
direction = 0
148-
}
149-
150140
if d.Wood == OakWood() {
151-
return "minecraft:wooden_door", map[string]any{"direction": int32(direction), "door_hinge_bit": d.Right, "open_bit": d.Open, "upper_block_bit": d.Top}
141+
return "minecraft:wooden_door", map[string]any{"minecraft:cardinal_direction": d.Facing.String(), "door_hinge_bit": d.Right, "open_bit": d.Open, "upper_block_bit": d.Top}
152142
}
153-
return "minecraft:" + d.Wood.String() + "_door", map[string]any{"direction": int32(direction), "door_hinge_bit": d.Right, "open_bit": d.Open, "upper_block_bit": d.Top}
143+
return "minecraft:" + d.Wood.String() + "_door", map[string]any{"minecraft:cardinal_direction": d.Facing.String(), "door_hinge_bit": d.Right, "open_bit": d.Open, "upper_block_bit": d.Top}
154144
}
155145

156146
// allDoors returns a list of all door types

server/block/wood_fence_gate.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ func (f WoodFenceGate) EncodeItem() (name string, meta int16) {
105105
// EncodeBlock ...
106106
func (f WoodFenceGate) EncodeBlock() (name string, properties map[string]any) {
107107
if f.Wood == OakWood() {
108-
return "minecraft:fence_gate", map[string]any{"direction": int32(horizontalDirection(f.Facing)), "open_bit": f.Open, "in_wall_bit": f.Lowered}
108+
return "minecraft:fence_gate", map[string]any{"minecraft:cardinal_direction": f.Facing.String(), "open_bit": f.Open, "in_wall_bit": f.Lowered}
109109
}
110-
return "minecraft:" + f.Wood.String() + "_fence_gate", map[string]any{"direction": int32(horizontalDirection(f.Facing)), "open_bit": f.Open, "in_wall_bit": f.Lowered}
110+
return "minecraft:" + f.Wood.String() + "_fence_gate", map[string]any{"minecraft:cardinal_direction": f.Facing.String(), "open_bit": f.Open, "in_wall_bit": f.Lowered}
111111
}
112112

113113
// Model ...

server/item/creative/category.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package creative
2+
3+
// Category represents a category of items in the creative inventory which are shown as different tabs.
4+
type Category struct {
5+
category
6+
}
7+
8+
type category uint8
9+
10+
// ConstructionCategory is the construction category which contains only blocks that do not fall under
11+
// any other category.
12+
func ConstructionCategory() Category {
13+
return Category{1}
14+
}
15+
16+
// NatureCategory is the nature category which contains blocks and items that can be naturally found in the
17+
// world.
18+
func NatureCategory() Category {
19+
return Category{2}
20+
}
21+
22+
// EquipmentCategory is the equipment category which contains tools, armour, food and any other form of
23+
// equipment.
24+
func EquipmentCategory() Category {
25+
return Category{3}
26+
}
27+
28+
// ItemsCategory is the items category for all the miscellaneous items that do not fall under any other
29+
// category.
30+
func ItemsCategory() Category {
31+
return Category{4}
32+
}
33+
34+
// Uint8 returns the category type as a uint8.
35+
func (s category) Uint8() uint8 {
36+
return uint8(s)
37+
}

server/item/creative/creative.go

+117-46
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package creative
22

33
import (
44
_ "embed"
5+
"fmt"
56
"github.com/df-mc/dragonfly/server/internal/nbtconv"
67
// The following four imports are essential for this package: They make sure this package is loaded after
78
// all these imports. This ensures that all blocks and items are registered before the creative items are
@@ -12,90 +13,160 @@ import (
1213
"github.com/sandertv/gophertunnel/minecraft/nbt"
1314
)
1415

16+
// Item represents a registered item in the creative inventory. It holds a stack of the item and a group that
17+
// the item is part of.
18+
type Item struct {
19+
// Stack is the stack of the item that is registered in the creative inventory.
20+
Stack item.Stack
21+
// Group is the name of the group that the item is part of. If two groups are registered with the same
22+
// name, the item will always reside in the first group that was registered.
23+
Group string
24+
}
25+
26+
// Group represents a group of items in the creative inventory. Each group has a category, a name and an icon.
27+
// If either the name or icon is empty, the group is considered an 'anonymous group' and will not group its
28+
// contents together in the creative inventory.
29+
type Group struct {
30+
// Category is the category of the group. It determines the tab in which the group will be displayed in the
31+
// creative inventory.
32+
Category Category
33+
// Name is the localised name of the group, i.e. "itemGroup.name.planks".
34+
Name string
35+
// Icon is the item that will be displayed as the icon of the group in the creative inventory.
36+
Icon item.Stack
37+
}
38+
39+
// Groups returns a list with all groups that have been registered as a creative group. These groups will be
40+
// accessible by players in-game who have creative mode enabled.
41+
func Groups() []Group {
42+
return creativeGroups
43+
}
44+
45+
// RegisterGroup registers a group as a creative group, exposing it in the creative inventory. It can then
46+
// be referenced using its name when calling RegisterItem.
47+
func RegisterGroup(group Group) {
48+
creativeGroups = append(creativeGroups, group)
49+
}
50+
1551
// Items returns a list with all items that have been registered as a creative item. These items will
1652
// be accessible by players in-game who have creative mode enabled.
17-
func Items() []item.Stack {
53+
func Items() []Item {
1854
return creativeItemStacks
1955
}
2056

2157
// RegisterItem registers an item as a creative item, exposing it in the creative inventory.
22-
func RegisterItem(item item.Stack) {
58+
func RegisterItem(item Item) {
2359
creativeItemStacks = append(creativeItemStacks, item)
2460
}
2561

2662
var (
2763
//go:embed creative_items.nbt
2864
creativeItemData []byte
65+
66+
// creativeGroups holds a list of all groups that were registered to the creative inventory using
67+
// RegisterGroup.
68+
creativeGroups []Group
2969
// creativeItemStacks holds a list of all item stacks that were registered to the creative inventory using
3070
// RegisterItem.
31-
creativeItemStacks []item.Stack
71+
creativeItemStacks []Item
3272
)
3373

74+
// creativeGroupEntry holds data of a creative group as present in the creative inventory.
75+
type creativeGroupEntry struct {
76+
Category int32 `nbt:"category"`
77+
Name string `nbt:"name"`
78+
Icon creativeItemEntry `nbt:"icon"`
79+
}
80+
3481
// creativeItemEntry holds data of a creative item as present in the creative inventory.
3582
type creativeItemEntry struct {
3683
Name string `nbt:"name"`
3784
Meta int16 `nbt:"meta"`
3885
NBT map[string]any `nbt:"nbt,omitempty"`
3986
BlockProperties map[string]any `nbt:"block_properties,omitempty"`
87+
GroupIndex int32 `nbt:"group_index,omitempty"`
4088
}
4189

4290
// init initialises the creative items, registering all creative items that have also been registered as
4391
// normal items and are present in vanilla.
4492
func init() {
45-
var m []creativeItemEntry
93+
var m struct {
94+
Groups []creativeGroupEntry `nbt:"groups"`
95+
Items []creativeItemEntry `nbt:"items"`
96+
}
4697
if err := nbt.Unmarshal(creativeItemData, &m); err != nil {
4798
panic(err)
4899
}
49-
for _, data := range m {
50-
var (
51-
it world.Item
52-
ok bool
53-
)
54-
if len(data.BlockProperties) > 0 {
55-
// Item with a block, try parsing the block, then try asserting that to an item. Blocks no longer
56-
// have their metadata sent, but we still need to get that metadata in order to be able to register
57-
// different block states as different items.
58-
if b, ok := world.BlockByName(data.Name, data.BlockProperties); ok {
59-
if it, ok = b.(world.Item); !ok {
60-
continue
61-
}
62-
}
63-
} else {
64-
if it, ok = world.ItemByName(data.Name, data.Meta); !ok {
65-
// The item wasn't registered, so don't register it as a creative item.
66-
continue
67-
}
68-
if _, resultingMeta := it.EncodeItem(); resultingMeta != data.Meta {
69-
// We found an item registered with that ID and a meta of 0, but we only need items with strictly
70-
// the same meta here.
71-
continue
72-
}
100+
for i, group := range m.Groups {
101+
name := group.Name
102+
if name == "" {
103+
name = fmt.Sprint("anon", i)
104+
}
105+
st, _ := itemStackFromEntry(group.Icon)
106+
c := Category{category(group.Category)}
107+
RegisterGroup(Group{Category: c, Name: name, Icon: st})
108+
}
109+
for _, data := range m.Items {
110+
if data.GroupIndex >= int32(len(creativeGroups)) {
111+
panic(fmt.Errorf("invalid group index %v for item %v", data.GroupIndex, data.Name))
112+
}
113+
st, ok := itemStackFromEntry(data)
114+
if !ok {
115+
continue
73116
}
117+
RegisterItem(Item{st, creativeGroups[data.GroupIndex].Name})
118+
}
119+
}
74120

75-
if n, ok := it.(world.NBTer); ok {
76-
if len(data.NBT) > 0 {
77-
it = n.DecodeNBT(data.NBT).(world.Item)
121+
func itemStackFromEntry(data creativeItemEntry) (item.Stack, bool) {
122+
var (
123+
it world.Item
124+
ok bool
125+
)
126+
if len(data.BlockProperties) > 0 {
127+
// Item with a block, try parsing the block, then try asserting that to an item. Blocks no longer
128+
// have their metadata sent, but we still need to get that metadata in order to be able to register
129+
// different block states as different items.
130+
if b, ok := world.BlockByName(data.Name, data.BlockProperties); ok {
131+
if it, ok = b.(world.Item); !ok {
132+
return item.Stack{}, false
78133
}
79134
}
135+
} else {
136+
if it, ok = world.ItemByName(data.Name, data.Meta); !ok {
137+
// The item wasn't registered, so don't register it as a creative item.
138+
return item.Stack{}, false
139+
}
140+
if _, resultingMeta := it.EncodeItem(); resultingMeta != data.Meta {
141+
// We found an item registered with that ID and a meta of 0, but we only need items with strictly
142+
// the same meta here.
143+
return item.Stack{}, false
144+
}
145+
}
80146

81-
st := item.NewStack(it, 1)
147+
if n, ok := it.(world.NBTer); ok {
82148
if len(data.NBT) > 0 {
83-
var invalid bool
84-
for _, e := range nbtconv.Slice(data.NBT, "ench") {
85-
if v, ok := e.(map[string]any); ok {
86-
t, ok := item.EnchantmentByID(int(nbtconv.Int16(v, "id")))
87-
if !ok {
88-
invalid = true
89-
break
90-
}
91-
st = st.WithEnchantments(item.NewEnchantment(t, int(nbtconv.Int16(v, "lvl"))))
149+
it = n.DecodeNBT(data.NBT).(world.Item)
150+
}
151+
}
152+
153+
st := item.NewStack(it, 1)
154+
if len(data.NBT) > 0 {
155+
var invalid bool
156+
for _, e := range nbtconv.Slice(data.NBT, "ench") {
157+
if v, ok := e.(map[string]any); ok {
158+
t, ok := item.EnchantmentByID(int(nbtconv.Int16(v, "id")))
159+
if !ok {
160+
invalid = true
161+
break
92162
}
163+
st = st.WithEnchantments(item.NewEnchantment(t, int(nbtconv.Int16(v, "lvl"))))
93164
}
94-
if invalid {
95-
// Invalid enchantment, skip this item.
96-
continue
97-
}
98165
}
99-
RegisterItem(st)
166+
if invalid {
167+
// Invalid enchantment, skip this item.
168+
return item.Stack{}, false
169+
}
100170
}
171+
return st, true
101172
}
36.8 KB
Binary file not shown.

server/item/recipe/crafting_data.nbt

305 Bytes
Binary file not shown.

server/item/recipe/furnace_data.nbt

0 Bytes
Binary file not shown.

server/item/recipe/potion_data.nbt

0 Bytes
Binary file not shown.

server/player/player.go

+16-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ type playerData struct {
6666

6767
cooldowns map[string]time.Time
6868

69-
speed float64
70-
flightSpeed float64
69+
speed float64
70+
flightSpeed float64
71+
verticalFlightSpeed float64
7172

7273
health *entity.HealthManager
7374
experience *entity.ExperienceManager
@@ -473,6 +474,19 @@ func (p *Player) FlightSpeed() float64 {
473474
return p.flightSpeed
474475
}
475476

477+
// SetVerticalFlightSpeed sets the flight speed of the player on the Y axis. The value passed represents the
478+
// base speed, which is the blocks/tick speed that the player will obtain while flying.
479+
func (p *Player) SetVerticalFlightSpeed(flightSpeed float64) {
480+
p.verticalFlightSpeed = flightSpeed
481+
p.session().SendAbilities(p)
482+
}
483+
484+
// VerticalFlightSpeed returns the flight speed of the player on the Y axis, with the value representing the
485+
// base speed. The default vertical flight speed of a player is 1.0, which corresponds to 1 block/tick.
486+
func (p *Player) VerticalFlightSpeed() float64 {
487+
return p.verticalFlightSpeed
488+
}
489+
476490
// Health returns the current health of the player. It will always be lower than Player.MaxHealth().
477491
func (p *Player) Health() float64 {
478492
return p.health.Health()

0 commit comments

Comments
 (0)