up3
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
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
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user