Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ require (
github.com/brentp/intintmap v0.0.0-20251106190759-56907b1f8479
github.com/cespare/xxhash/v2 v2.3.0
github.com/df-mc/goleveldb v1.1.9
github.com/df-mc/worldupgrader v1.0.20
github.com/df-mc/worldupgrader v1.0.21
github.com/go-gl/mathgl v1.2.0
github.com/google/uuid v1.6.0
github.com/pelletier/go-toml v1.9.5
github.com/sandertv/gophertunnel v1.56.2
github.com/sandertv/gophertunnel v1.57.0
github.com/segmentio/fasthash v1.0.3
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329
golang.org/x/mod v0.22.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ github.com/df-mc/goleveldb v1.1.9 h1:ihdosZyy5jkQKrxucTQmN90jq/2lUwQnJZjIYIC/9YU
github.com/df-mc/goleveldb v1.1.9/go.mod h1:+NHCup03Sci5q84APIA21z3iPZCuk6m6ABtg4nANCSk=
github.com/df-mc/jsonc v1.0.5 h1:O7oh07kbS5AYY+l2Fji6l4h0iHcdjKbxCtK5VlZlLMU=
github.com/df-mc/jsonc v1.0.5/go.mod h1:+Q++JuCE9IKiP8v7sWImdf/RjQX0nfXyfX6PdfTTmc4=
github.com/df-mc/worldupgrader v1.0.20 h1:wfJyG3bFeaM/HXy7TCiO4HKVw3Mf3N4gPFmgxMHsKnc=
github.com/df-mc/worldupgrader v1.0.20/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk=
github.com/df-mc/worldupgrader v1.0.21 h1:Qr4/QB8ek7En0vkTuRXYq4FrZM0HHSOXsJOL7Ko4Cjg=
github.com/df-mc/worldupgrader v1.0.21/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-gl/mathgl v1.2.0 h1:v2eOj/y1B2afDxF6URV1qCYmo1KW08lAMtTbOn3KXCY=
github.com/go-gl/mathgl v1.2.0/go.mod h1:pf9+b5J3LFP7iZ4XXaVzZrCle0Q/vNpB/vDe5+3ulRE=
Expand Down Expand Up @@ -41,8 +41,8 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/sandertv/go-raknet v1.15.1-0.20260112202637-beca0b10c217 h1:UZQq2253Q+7co/C9Et62RYPBggzz+L+2yqGlvQhSNM8=
github.com/sandertv/go-raknet v1.15.1-0.20260112202637-beca0b10c217/go.mod h1:/yysjwfCXm2+2OY8mBazLzcxJ3irnylKCyG3FLgUPVU=
github.com/sandertv/gophertunnel v1.56.2 h1:eFc58AkMQo43ntR0Wmvz8GRFSdOgABKVDn52GMbIYag=
github.com/sandertv/gophertunnel v1.56.2/go.mod h1:F8+ZPbzxJ0LqunXEaDjqeyUgHVB0rI5ZU+PHnptXGfI=
github.com/sandertv/gophertunnel v1.57.0 h1:UkgVg1xLCsOSm79rP09WmodGSHgA8M7+l4quL01cIL8=
github.com/sandertv/gophertunnel v1.57.0/go.mod h1:W4VnrX9AIPIVXNDMEIKMIRj1T80EdOgdqXpGbQpyAbE=
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588=
Expand Down
Binary file modified server/item/creative/creative_items.nbt
Binary file not shown.
Binary file modified server/item/recipe/crafting_data.nbt
Binary file not shown.
Binary file modified server/item/recipe/potion_data.nbt
Binary file not shown.
4 changes: 2 additions & 2 deletions server/player/bossbar/colour.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func Purple() Colour {
return Colour{colour(5)}
}

// DarkPurple is the colour for a dark purple boss bar.
func DarkPurple() Colour {
// RebeccaPurple is the colour for a rebecca purple boss bar.
func RebeccaPurple() Colour {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seriously?

return Colour{colour(6)}
}

Expand Down
92 changes: 92 additions & 0 deletions server/player/debug/shape.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,95 @@ type Text struct {
// Entity is an optional entity handle to attach the shape to.
Entity *world.EntityHandle
}

// Cylinder represents a hollow cylinder, or frustum, that can be drawn at any point in the world, with a
// height running up the Y axis. The base and top each have their own radius on the X and Z axes, allowing
// for tapered and elliptical cylinders. A Cone is the special case of a Cylinder with a zero top radius.
type Cylinder struct {
shape

// Colour is the colour that will be used for the outline. If empty, it will default to white.
Colour color.RGBA
// Position is the origin position of the shape in the world.
Position mgl64.Vec3
// Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0.
Scale float64
// BaseRadius is the radius of the cylinder's base along the X and Z axes. If empty, it will default to a
// radius of 1.0 on each axis. Differing X and Z radii produce an elliptical cylinder.
BaseRadius mgl64.Vec2
// TopRadius is the radius of the cylinder's top along the X and Z axes. If empty, it will default to
// BaseRadius, producing a straight cylinder. A smaller TopRadius tapers the cylinder into a frustum.
TopRadius mgl64.Vec2
// Height is the height of the cylinder. If zero, it will default to 1.0.
Height float64
// Segments is the number of segments that the cylinder will be drawn with. The more segments, the
// smoother the cylinder will look. If zero, it will default to 20.
Segments int
// Entity is an optional entity handle to attach the shape to.
Entity *world.EntityHandle
}

// Pyramid represents a pyramid that can be drawn at any point in the world, with a base on the X and Z axes
// and a height running up the Y axis to a single apex.
type Pyramid struct {
shape

// Colour is the colour that will be used for the outline. If empty, it will default to white.
Colour color.RGBA
// Position is the origin position of the shape in the world.
Position mgl64.Vec3
// Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0.
Scale float64
// Width is the width along the X axis of the pyramid base. If zero, it will default to 1.0.
Width float64
// Depth is the depth along the Z axis of the pyramid base. If zero, it will default to Width.
Depth float64
// Height is the height of the pyramid. If zero, it will default to 1.0.
Height float64
// Entity is an optional entity handle to attach the shape to.
Entity *world.EntityHandle
}

// Ellipsoid represents a hollow ellipsoid that can be drawn at any point in the world, with a radius along
// each of the X, Y and Z axes.
type Ellipsoid struct {
shape

// Colour is the colour that will be used for the outline. If empty, it will default to white.
Colour color.RGBA
// Position is the origin position of the shape in the world.
Position mgl64.Vec3
// Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0.
Scale float64
// Radii are the radii of the ellipsoid along the X, Y and Z axes. If empty, it will default to a radius
// of 1.0 on each axis.
Radii mgl64.Vec3
// SegmentsPerAxis is the number of segments that the ellipsoid will be drawn with per axis. The more
// segments, the smoother the ellipsoid will look. If zero, it will default to 20.
SegmentsPerAxis int
// Entity is an optional entity handle to attach the shape to.
Entity *world.EntityHandle
}

// Cone represents a cone that can be drawn at any point in the world, with a base on the X and Z axes and a
// height running up the Y axis to a single apex.
type Cone struct {
shape

// Colour is the colour that will be used for the outline. If empty, it will default to white.
Colour color.RGBA
// Position is the origin position of the shape in the world.
Position mgl64.Vec3
// Scale is the rate to scale the shape from its origin point. If zero, it will default to 1.0.
Scale float64
// Radii are the radii along the X and Z axes of the cone base. If empty, it will default to a radius of
// 1.0 on each axis.
Radii mgl64.Vec2
// Height is the height of the cone. If zero, it will default to 1.0.
Height float64
// Segments is the number of segments that the cone will be drawn with. The more segments, the smoother
// the cone will look. If zero, it will default to 20.
Segments int
// Entity is an optional entity handle to attach the shape to.
Entity *world.EntityHandle
}
65 changes: 59 additions & 6 deletions server/session/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,14 @@ func (s *Session) shapeAttachedEntityRuntimeID(shape debug.Shape) int64 {
handle = shape.Entity
case *debug.Text:
handle = shape.Entity
case *debug.Cylinder:
handle = shape.Entity
case *debug.Pyramid:
handle = shape.Entity
case *debug.Ellipsoid:
handle = shape.Entity
case *debug.Cone:
handle = shape.Entity
}
if handle == nil {
return 0
Expand All @@ -1138,7 +1146,7 @@ func debugShapeToProtocol(shape debug.Shape, dim world.Dimension, attachedEntity
white := color.RGBA{R: 255, G: 255, B: 255, A: 255}
switch shape := shape.(type) {
case *debug.Arrow:
ps.Type = protocol.Option(uint8(protocol.PrimitiveShapeArrow))
ps.Type = protocol.Option(protocol.PrimitiveShapeArrow)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.ExtraShapeData = &protocol.ArrowShape{
Expand All @@ -1148,30 +1156,30 @@ func debugShapeToProtocol(shape debug.Shape, dim world.Dimension, attachedEntity
Segments: protocol.Option(valueOrDefault(uint8(shape.HeadSegments), 4)),
}
case *debug.Box:
ps.Type = protocol.Option(uint8(protocol.PrimitiveShapeBox))
ps.Type = protocol.Option(protocol.PrimitiveShapeBox)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
ps.ExtraShapeData = &protocol.BoxShape{BoxBound: valueOrDefault(vec64To32(shape.Bounds), mgl32.Vec3{1, 1, 1})}
case *debug.Circle:
ps.Type = protocol.Option(uint8(protocol.PrimitiveShapeCircle))
ps.Type = protocol.Option(protocol.PrimitiveShapeCircle)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
ps.ExtraShapeData = &protocol.SphereShape{Segments: valueOrDefault(uint8(shape.Segments), 20)}
case *debug.Line:
ps.Type = protocol.Option(uint8(protocol.PrimitiveShapeLine))
ps.Type = protocol.Option(protocol.PrimitiveShapeLine)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.ExtraShapeData = &protocol.LineShape{LineEndLocation: vec64To32(shape.EndPosition)}
case *debug.Sphere:
ps.Type = protocol.Option(uint8(protocol.PrimitiveShapeSphere))
ps.Type = protocol.Option(protocol.PrimitiveShapeSphere)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
ps.ExtraShapeData = &protocol.SphereShape{Segments: valueOrDefault(uint8(shape.Segments), 20)}
case *debug.Text:
ps.Type = protocol.Option(uint8(protocol.PrimitiveShapeText))
ps.Type = protocol.Option(protocol.PrimitiveShapeText)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
Expand All @@ -1192,6 +1200,51 @@ func debugShapeToProtocol(shape debug.Shape, dim world.Dimension, attachedEntity
textData.BackgroundColour = protocol.Option(shape.BackgroundColour)
}
ps.ExtraShapeData = textData
case *debug.Cylinder:
ps.Type = protocol.Option(protocol.PrimitiveShapeCylinder)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
base := valueOrDefault(shape.BaseRadius, mgl64.Vec2{1, 1})
top := valueOrDefault(shape.TopRadius, base)
ps.ExtraShapeData = &protocol.CylinderShape{
RadiusX: mgl32.Vec2{float32(base[0]), float32(top[0])},
RadiusZ: mgl32.Vec2{float32(base[1]), float32(top[1])},
Height: valueOrDefault(float32(shape.Height), 1),
NumSegments: valueOrDefault(uint8(shape.Segments), 20),
}
case *debug.Pyramid:
ps.Type = protocol.Option(protocol.PrimitiveShapePyramid)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
pyramid := &protocol.PyramidShape{
Width: valueOrDefault(float32(shape.Width), 1),
Height: valueOrDefault(float32(shape.Height), 1),
}
if shape.Depth != 0 {
pyramid.Depth = protocol.Option(float32(shape.Depth))
}
ps.ExtraShapeData = pyramid
case *debug.Ellipsoid:
ps.Type = protocol.Option(protocol.PrimitiveShapeEllipsoid)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
ps.ExtraShapeData = &protocol.EllipsoidShape{
Radii: valueOrDefault(vec64To32(shape.Radii), mgl32.Vec3{1, 1, 1}),
SegmentsPerAxis: valueOrDefault(uint8(shape.SegmentsPerAxis), 20),
}
case *debug.Cone:
ps.Type = protocol.Option(protocol.PrimitiveShapeCone)
ps.Colour = protocol.Option(valueOrDefault(shape.Colour, white))
ps.Location = protocol.Option(vec64To32(shape.Position))
ps.Scale = protocol.Option(valueOrDefault(float32(shape.Scale), 1))
ps.ExtraShapeData = &protocol.ConeShape{
Radii: valueOrDefault(vec2To32(shape.Radii), mgl32.Vec2{1, 1}),
Height: valueOrDefault(float32(shape.Height), 1),
NumSegments: valueOrDefault(uint8(shape.Segments), 20),
}
default:
panic(fmt.Sprintf("unknown debug shape type %T", shape))
}
Expand Down
5 changes: 3 additions & 2 deletions server/session/text.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package session

import (
"time"

"github.com/df-mc/dragonfly/server/player/chat"
"github.com/df-mc/dragonfly/server/player/scoreboard"
"github.com/sandertv/gophertunnel/minecraft/protocol"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
"golang.org/x/text/language"
"time"
)

// SendMessage ...
Expand Down Expand Up @@ -145,7 +146,7 @@ func (s *Session) SendBossBar(text string, colour uint8, healthPercentage float6
EventType: packet.BossEventShow,
BossBarTitle: text,
HealthPercentage: float32(healthPercentage),
Colour: uint32(colour),
Colour: colour,
})
}

Expand Down
7 changes: 6 additions & 1 deletion server/session/world.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ func (s *Session) ViewParticle(pos mgl64.Vec3, p world.Particle) {
}

// tierToSoundEvent converts an item.ArmourTier to a sound event associated with equipping it.
func tierToSoundEvent(tier item.ArmourTier) uint32 {
func tierToSoundEvent(tier item.ArmourTier) string {
switch tier.(type) {
case item.ArmourTierLeather:
return packet.SoundEventEquipLeather
Expand Down Expand Up @@ -1413,6 +1413,11 @@ func vec64To32(vec3 mgl64.Vec3) mgl32.Vec3 {
return mgl32.Vec3{float32(vec3[0]), float32(vec3[1]), float32(vec3[2])}
}

// vec2To32 converts a mgl64.Vec2 to a mgl32.Vec2.
func vec2To32(vec2 mgl64.Vec2) mgl32.Vec2 {
return mgl32.Vec2{float32(vec2[0]), float32(vec2[1])}
}

// blockPosFromProtocol ...
func blockPosFromProtocol(pos protocol.BlockPos) cube.Pos {
return cube.Pos{int(pos.X()), int(pos.Y()), int(pos.Z())}
Expand Down
1 change: 1 addition & 0 deletions server/world/biome/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func init() {
world.RegisterBiome(SoulSandValley{})
world.RegisterBiome(StonyPeaks{})
world.RegisterBiome(StonyShore{})
world.RegisterBiome(SulfurCaves{})
world.RegisterBiome(SunflowerPlains{})
world.RegisterBiome(SwampHills{})
world.RegisterBiome(Swamp{})
Expand Down
46 changes: 46 additions & 0 deletions server/world/biome/sulfur_caves.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package biome

import "image/color"

// SulfurCaves ...
type SulfurCaves struct{}

// Temperature ...
func (SulfurCaves) Temperature() float64 {
return 0.8
}

// Rainfall ...
func (SulfurCaves) Rainfall() float64 {
return 0.4
}

// Depth ...
func (SulfurCaves) Depth() float64 {
return 0.1
}

// Scale ...
func (SulfurCaves) Scale() float64 {
return 0.2
}

// WaterColour ...
func (SulfurCaves) WaterColour() color.RGBA {
return color.RGBA{R: 0x60, G: 0xb7, B: 0xff, A: 0xa6}
}

// Tags ...
func (SulfurCaves) Tags() []string {
return []string{"caves", "sulfur_caves", "overworld", "monster"}
}

// String ...
func (SulfurCaves) String() string {
return "sulfur_caves"
}

// EncodeBiome ...
func (SulfurCaves) EncodeBiome() int {
return 194
}
Binary file modified server/world/block_states.nbt
Binary file not shown.
14 changes: 7 additions & 7 deletions server/world/chunk/chunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,14 @@ func (chunk *Chunk) SubY(index int16) int16 {
return (index << 4) + int16(chunk.r[0])
}

// HighestFilledSubChunk returns the index of the highest sub chunk in the chunk
// that has any blocks in it. 0 is returned if no subchunks have any blocks.
// HighestFilledSubChunk returns the number of sub chunks up to and including the
// highest sub chunk in the chunk that has any blocks in it. 0 is returned if no
// subchunks have any blocks.
func (chunk *Chunk) HighestFilledSubChunk() uint16 {
highest := uint16(0)
for highest = uint16(len(chunk.sub) - 1); highest > 0; highest-- {
if !chunk.sub[highest].Empty() {
break
for i, sub := range slices.Backward(chunk.sub) {
if !sub.Empty() {
return uint16(i + 1)
}
}
return highest
return 0
}
Binary file modified server/world/vanilla_items.nbt
Binary file not shown.