Skip to content

Instantly share code, notes, and snippets.

@JustTalDevelops
Created August 8, 2021 03:33
Show Gist options
  • Save JustTalDevelops/8234456721cba908b5827d986a54958e to your computer and use it in GitHub Desktop.
Save JustTalDevelops/8234456721cba908b5827d986a54958e to your computer and use it in GitHub Desktop.
Program to search Minecraft Bedrock world for chests (using the DF API)
package main
import (
"fmt"
"github.com/df-mc/dragonfly/server/block"
"github.com/df-mc/dragonfly/server/block/cube"
"github.com/df-mc/dragonfly/server/world"
"github.com/df-mc/dragonfly/server/world/chunk"
"github.com/df-mc/dragonfly/server/world/mcdb"
"sync"
)
// findChestPositions finds all chests in a world. First, it gets all generated chunks, and then
// loads each chunk and checks it for chests. When it's done, it closes the DB and returns the
// positions that it found.
func findChestPositions(worldPath string) ([]cube.Pos, error){
chestRuntimeID, ok := world.BlockRuntimeID(block.Chest{})
if !ok {
return nil, fmt.Errorf("could not find chest runtime ID")
}
db, err := mcdb.New(worldPath)
if err != nil {
return nil, err
}
chunks := make(map[world.ChunkPos]*chunk.Chunk)
propagateChunk(db, chunks, world.ChunkPos{})
err = db.Close()
if err != nil {
return nil, err
}
var wg sync.WaitGroup
var chestPositions []cube.Pos
for pos, ch := range chunks {
pos := pos
ch := ch
wg.Add(1)
go func() {
offsetX := pos.X() << 4
offsetZ := pos.Z() << 4
for y := 0; y < 256; y++ {
for x := 0; x < 16; x++ {
for z := 0; z < 16; z++ {
blockPos := cube.Pos{int(offsetX) + x, y, int(offsetZ) + z}
runtimeId := ch.RuntimeID(uint8(blockPos.X()), int16(blockPos.Y()), uint8(blockPos.Z()), 0)
if runtimeId == chestRuntimeID {
chestPositions = append(chestPositions, blockPos)
}
}
}
}
wg.Done()
}()
}
wg.Wait()
return chestPositions, nil
}
// propagateChunk propagates a chunk in the chunks map, and then it's neighbours, until there are no chunks left.
func propagateChunk(db *mcdb.Provider, chunks map[world.ChunkPos]*chunk.Chunk, pos world.ChunkPos) {
if _, ok := chunks[pos]; ok {
return
}
c, exists, err := db.LoadChunk(pos)
if err != nil {
panic(err)
}
if !exists {
return
}
chunks[pos] = c
propagateChunk(db, chunks, world.ChunkPos{pos.X(), pos.Z() + 1})
propagateChunk(db, chunks, world.ChunkPos{pos.X(), pos.Z() - 1})
propagateChunk(db, chunks, world.ChunkPos{pos.X() + 1, pos.Z()})
propagateChunk(db, chunks, world.ChunkPos{pos.X() - 1, pos.Z()})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment