Skip to content

Commit

Permalink
Cleaned up interaction between mcdb and world.
Browse files Browse the repository at this point in the history
No more EntityRegistry in mcdb, now we can more easily use the new format for entities.
  • Loading branch information
Sandertv committed Oct 28, 2024
1 parent f7ff3ab commit b4a6287
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 200 deletions.
4 changes: 2 additions & 2 deletions server/player/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -1827,7 +1827,7 @@ func (p *Player) PickBlock(pos cube.Pos) {

if found {
if slot < 9 {
_ = p.session().SetHeldSlot(slot)
_ = p.session().SetHeldSlot(slot, p.tx, p)
return
}
_ = p.Inventory().Swap(slot, int(*p.heldSlot))
Expand All @@ -1840,7 +1840,7 @@ func (p *Player) PickBlock(pos cube.Pos) {
return
}
if firstEmpty < 8 {
_ = p.session().SetHeldSlot(firstEmpty)
_ = p.session().SetHeldSlot(firstEmpty, p.tx, p)
_ = p.Inventory().SetItem(firstEmpty, pickedItem)
return
}
Expand Down
13 changes: 6 additions & 7 deletions server/player/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,13 @@ type Config struct {
Session *session.Session
}

func (t Type) Init(conf any, data *world.EntityData) {
cfg, _ := conf.(Config)
locale, err := language.Parse(strings.Replace(cfg.Locale, "_", "-", 1))
func (conf Config) Apply(data *world.EntityData) {
locale, err := language.Parse(strings.Replace(conf.Locale, "_", "-", 1))
if err != nil {
locale = language.BritishEnglish
}
data.Name = cfg.Name
data.Pos = cfg.Pos
data.Name = conf.Name
data.Pos = conf.Pos
data.Data = &playerData{
inv: inventory.New(36, nil),
enderChest: inventory.New(27, nil),
Expand All @@ -51,12 +50,12 @@ func (t Type) Init(conf any, data *world.EntityData) {
mc: &entity.MovementComputer{Gravity: 0.08, Drag: 0.02, DragBeforeGravity: true},
heldSlot: new(uint32),
gameMode: world.GameModeSurvival,
skin: cfg.Skin,
skin: conf.Skin,
airSupplyTicks: 300,
maxAirSupplyTicks: 300,
enchantSeed: rand.Int63(),
scale: 1.0,
s: cfg.Session,
s: conf.Session,
}
}

Expand Down
2 changes: 1 addition & 1 deletion server/session/handler_container_close.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type ContainerCloseHandler struct{}
func (h *ContainerCloseHandler) Handle(p packet.Packet, s *Session, tx *world.Tx, c Controllable) error {
pk := p.(*packet.ContainerClose)

s.EmptyUIInventory()
s.EmptyUIInventory(c)
switch pk.WindowID {
case 0:
// Closing of the normal inventory.
Expand Down
20 changes: 10 additions & 10 deletions server/session/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,23 @@ func (s *Session) closeCurrentContainer(tx *world.Tx) {

// EmptyUIInventory attempts to move all items in the UI inventory to the player's main inventory. If the main inventory
// is full, the items are dropped on the ground instead.
func (s *Session) EmptyUIInventory() {
func (s *Session) EmptyUIInventory(c Controllable) {
if s == Nop {
return
}
for _, i := range s.ui.Clear() {
if n, err := s.inv.AddItem(i); err != nil {
// We couldn't add the item to the main inventory (probably because
// it was full), so we drop it instead.
s.c.Drop(i.Grow(i.Count() - n))
c.Drop(i.Grow(i.Count() - n))
}
}
}

// SendRespawn spawns the Controllable entity of the session client-side in the world, provided it has died.
func (s *Session) SendRespawn(pos mgl64.Vec3) {
func (s *Session) SendRespawn(pos mgl64.Vec3, c Controllable) {
s.writePacket(&packet.Respawn{
Position: vec64To32(pos.Add(entityOffset(s.c))),
Position: vec64To32(pos.Add(entityOffset(c))),
State: packet.RespawnStateReadyToSpawn,
EntityRuntimeID: selfEntityRuntimeID,
})
Expand Down Expand Up @@ -520,7 +520,7 @@ func (s *Session) EnableInstantRespawn(enable bool) {

// addToPlayerList adds the player of a session to the player list of this session. It will be shown in the
// in-game pause menu screen.
func (s *Session) addToPlayerList(session *Session) {
func (s *Session) addToPlayerList(session *Session, c Controllable) {
runtimeID := uint64(1)
s.entityMutex.Lock()
if session != s {
Expand Down Expand Up @@ -663,18 +663,18 @@ func (s *Session) broadcastArmourFunc(tx *world.Tx, c Controllable) func(slot in
}

// SetHeldSlot sets the currently held hotbar slot.
func (s *Session) SetHeldSlot(slot int) error {
func (s *Session) SetHeldSlot(slot int, tx *world.Tx, c Controllable) error {
if slot > 8 {
return fmt.Errorf("slot exceeds hotbar range 0-8: slot is %v", slot)
}

s.heldSlot.Store(uint32(slot))
*s.heldSlot = uint32(slot)

for _, viewer := range s.c.World().Viewers(s.c.Position()) {
viewer.ViewEntityItems(s.c)
for _, viewer := range tx.Viewers(c.Position()) {
viewer.ViewEntityItems(c)
}

mainHand, _ := s.c.HeldItems()
mainHand, _ := c.HeldItems()
s.writePacket(&packet.MobEquipment{
EntityRuntimeID: selfEntityRuntimeID,
NewItem: instanceFromItem(mainHand),
Expand Down
21 changes: 21 additions & 0 deletions server/world/chunk/col.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package chunk

import (
"github.com/df-mc/dragonfly/server/block/cube"
)

type Column struct {
Chunk *Chunk
Entities []Entity
BlockEntities []BlockEntity
}

type BlockEntity struct {
Pos cube.Pos
Data map[string]any
}

type Entity struct {
ID int64
Data map[string]any
}
9 changes: 6 additions & 3 deletions server/world/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
type AdvancedEntityType interface {
EntityType

Init(conf any, data *EntityData)
From(tx *Tx, handle *EntityHandle, data *EntityData) Entity
}

Expand All @@ -28,9 +27,13 @@ type EntityHandle struct {
// HANDLER?? HANDLE WORLD CHANGE HERE
}

func NewEntity(t AdvancedEntityType, conf any) *EntityHandle {
type EntityConfig interface {
Apply(data *EntityData)
}

func NewEntity(t AdvancedEntityType, conf EntityConfig) *EntityHandle {
handle := &EntityHandle{id: uuid.New(), t: t}
t.Init(conf, &handle.data)
conf.Apply(&handle.data)
return handle
}

Expand Down
40 changes: 8 additions & 32 deletions server/world/mcdb/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package mcdb

import (
"fmt"
"github.com/df-mc/dragonfly/server/entity"
"github.com/df-mc/dragonfly/server/world"
"github.com/df-mc/dragonfly/server/world/mcdb/leveldat"
"github.com/df-mc/goleveldb/leveldb"
"github.com/df-mc/goleveldb/leveldb/opt"
Expand All @@ -17,23 +15,9 @@ type Config struct {
// Log is the Logger that will be used to log errors and debug messages to.
// If set to nil, Log is set to slog.Default().
Log *slog.Logger
// Compression specifies the compression to use for compressing new data in
// the database. Decompression of the database will happen based on IDs
// found in the compressed blocks and is therefore uninfluenced by this
// field. If left empty, Compression will default to opt.FlateCompression.
Compression opt.Compression
// BlockSize specifies the size of blocks to be compressed. The default
// value, when left empty, is 16KiB (16 * opt.KiB). Higher values generally
// lead to better compression ratios at the expense of slightly higher
// memory usage while (de)compressing.
BlockSize int
// ReadOnly opens the DB in read-only mode. This will leave the data in the
// database unedited.
ReadOnly bool

// Entities is an EntityRegistry with all entity types registered that may
// be read from the DB. Entities will default to entity.DefaultRegistry.
Entities world.EntityRegistry
// LDBOptions holds LevelDB specific default options, such as the block size
// or compression used in the database.
LDBOptions *opt.Options
}

// Open creates a new DB reading and writing from/to files under the path
Expand All @@ -45,11 +29,11 @@ func (conf Config) Open(dir string) (*DB, error) {
conf.Log = slog.Default()
}
conf.Log = conf.Log.With("provider", "mcdb")
if conf.BlockSize == 0 {
conf.BlockSize = 16 * opt.KiB
if conf.LDBOptions == nil {
conf.LDBOptions = new(opt.Options)
}
if len(conf.Entities.Types()) == 0 {
conf.Entities = entity.DefaultRegistry
if conf.LDBOptions.BlockSize == 0 {
conf.LDBOptions.BlockSize = 16 * opt.KiB
}
_ = os.MkdirAll(filepath.Join(dir, "db"), 0777)

Expand All @@ -62,10 +46,6 @@ func (conf Config) Open(dir string) (*DB, error) {
if err != nil {
return nil, fmt.Errorf("open db: read level.dat: %w", err)
}

// TODO: Perform proper conversion here. Dragonfly stored 3 for a long
// time even though the fields were up to date, so we have to accept
// older ones no matter what.
ver := ldat.Ver()
if ver != leveldat.Version && ver >= 10 {
return nil, fmt.Errorf("open db: level.dat version %v is unsupported", ver)
Expand All @@ -75,11 +55,7 @@ func (conf Config) Open(dir string) (*DB, error) {
}
}
db.set = db.ldat.Settings()
ldb, err := leveldb.OpenFile(filepath.Join(dir, "db"), &opt.Options{
Compression: conf.Compression,
BlockSize: conf.BlockSize,
ReadOnly: conf.ReadOnly,
})
ldb, err := leveldb.OpenFile(filepath.Join(dir, "db"), conf.LDBOptions)
if err != nil {
return nil, fmt.Errorf("open db: leveldb: %w", err)
}
Expand Down
Loading

0 comments on commit b4a6287

Please sign in to comment.