Created
August 8, 2021 03:33
-
-
Save JustTalDevelops/8234456721cba908b5827d986a54958e to your computer and use it in GitHub Desktop.
Program to search Minecraft Bedrock world for chests (using the DF API)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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