Files
mc/server/world/mcdb/conf.go
T
TarnaWijaya 26ed99fda6
Build and deploy / Build (push) Has been cancelled
Build and deploy / Update Contributors (push) Has been cancelled
Build and deploy / Deploy (push) Has been cancelled
up3
2026-07-09 08:33:57 +08:00

73 lines
2.3 KiB
Go

package mcdb
import (
"fmt"
"log/slog"
"os"
"path/filepath"
"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"
)
// Config holds the optional parameters of a DB.
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
// LDBOptions holds LevelDB specific default options, such as the block size
// or compression used in the database.
LDBOptions *opt.Options
// Blocks is the BlockRegistry used for chunk decoding/encoding. If nil, world.DefaultBlockRegistry is used.
// When using a non-default registry, pass the same registry used by the World.
Blocks world.BlockRegistry
}
// Open creates a new DB reading and writing from/to files under the path
// passed. If a world is present at the path, Open will parse its data and
// initialise the world with it. If the data cannot be parsed, an error is
// returned.
func (conf Config) Open(dir string) (*DB, error) {
if conf.Log == nil {
conf.Log = slog.Default()
}
conf.Log = conf.Log.With("provider", "mcdb")
if conf.LDBOptions == nil {
conf.LDBOptions = new(opt.Options)
}
if conf.LDBOptions.BlockSize == 0 {
conf.LDBOptions.BlockSize = 16 * opt.KiB
}
_ = os.MkdirAll(filepath.Join(dir, "db"), 0777)
db := &DB{conf: conf, dir: dir, ldat: &leveldat.Data{}}
db.SetBlockRegistry(conf.Blocks)
if _, err := os.Stat(filepath.Join(dir, "level.dat")); os.IsNotExist(err) {
// A level.dat was not currently present for the world.
db.ldat.FillDefault()
} else {
ldat, err := leveldat.ReadFile(filepath.Join(dir, "level.dat"))
if err != nil {
return nil, fmt.Errorf("open db: read level.dat: %w", err)
}
ver := ldat.Ver()
if ver != leveldat.Version && ver >= 10 {
return nil, fmt.Errorf("open db: level.dat version %v is unsupported", ver)
}
if err = ldat.Unmarshal(db.ldat); err != nil {
return nil, fmt.Errorf("open db: unmarshal level.dat: %w", err)
}
}
db.set = db.ldat.Settings()
ldb, err := leveldb.OpenFile(filepath.Join(dir, "db"), conf.LDBOptions)
if err != nil {
return nil, fmt.Errorf("open db: leveldb: %w", err)
}
db.ldb = ldb
return db, nil
}