Skip to content

Instantly share code, notes, and snippets.

@shoghicp shoghicp/worldFixer.php
Last active Jul 4, 2018

Embed
What would you like to do?
This code will: Recreate lost signs, furnaces and chests, and remove invalid or corrupt tile entities from a world.
<?php
$world = $this->getServer()->getDefaultLevel();
$radius = 80;
$total = (($radius * 2) + 1) ** 2;
$count = 0;
for($chunkX = -$radius; $chunkX <= $radius; ++$chunkX){
for($chunkZ = -$radius; $chunkZ <= $radius; ++$chunkZ){
$chunk = $world->getChunk($chunkX, $chunkZ, false);
if($chunk instanceof \pocketmine\level\format\FullChunk and $chunk->isPopulated()){
$tiles = [];
$save = false;
foreach($chunk->getTiles() as $tile){
$x = $tile->x & 0x0f;
$y = $tile->y;
$z = $tile->z & 0x0f;
$blockId = $chunk->getBlockId($x, $y, $z);
if(isset($tiles["$x:$y:$z"])){
echo "Found duplicated tile in chunk $chunkX, $chunkZ [$x:$y:$z]\n";
$tile->close();
$save = true;
}elseif($tile instanceof \pocketmine\tile\Chest){
if($blockId !== 54){
echo "Found corrupt chest in chunk $chunkX, $chunkZ [$x:$y:$z]\n";
$tile->close();
$save = true;
}
}elseif($tile instanceof \pocketmine\tile\Sign){
if($blockId !== 63 and $blockId !== 68){
echo "Found corrupt sign in chunk $chunkX, $chunkZ [$x:$y:$z]\n";
$tile->close();
$save = true;
}
}elseif($tile instanceof \pocketmine\tile\Furnace){
if($blockId !== 61 and $blockId !== 62){
echo "Found corrupt furnace in chunk $chunkX, $chunkZ [$x:$y:$z]\n";
$tile->close();
$save = true;
}
}
$tiles["$x:$y:$z"] = true;
}
for($x = 0; $x < 16; ++$x){
for($z = 0; $z < 16; ++$z){
for($y = 0; $y < 128; ++$y){
if(!isset($tiles["$x:$y:$z"])){
$blockId = $chunk->getBlockId($x, $y, $z);
if($blockId === 54){
echo "Found non-tile chest in chunk $chunkX, $chunkZ [$x:$y:$z]\n";
$nbt = new \pocketmine\nbt\tag\Compound(false, [
new \pocketmine\nbt\tag\Enum("Items", []),
new \pocketmine\nbt\tag\String("id", \pocketmine\tile\Tile::CHEST),
new \pocketmine\nbt\tag\Int("x", $chunkX * 16 + $x),
new \pocketmine\nbt\tag\Int("y", $y),
new \pocketmine\nbt\tag\Int("z", $chunkZ * 16 + $z)
]);
$nbt->Items->setTagType(\pocketmine\nbt\NBT::TAG_Compound);
new \pocketmine\tile\Chest($chunk, $nbt);
$save = true;
}elseif($blockId === 61 or $blockId === 62){
echo "Found non-tile furnace in chunk $chunkX, $chunkZ [$x:$y:$z]\n";
$nbt = new \pocketmine\nbt\tag\Compound(false, [
new \pocketmine\nbt\tag\Enum("Items", []),
new \pocketmine\nbt\tag\String("id", \pocketmine\tile\Tile::FURNACE),
new \pocketmine\nbt\tag\Int("x", $chunkX * 16 + $x),
new \pocketmine\nbt\tag\Int("y", $y),
new \pocketmine\nbt\tag\Int("z", $chunkZ * 16 + $z)
]);
$nbt->Items->setTagType(\pocketmine\nbt\NBT::TAG_Compound);
new \pocketmine\tile\Furnace($chunk, $nbt);
$save = true;
}elseif($blockId === 63 or $blockId === 68){
echo "Found non-tile sign in chunk $chunkX, $chunkZ [$x:$y:$z]\n";
$nbt = new \pocketmine\nbt\tag\Compound(false, [
new \pocketmine\nbt\tag\String("id", \pocketmine\tile\Tile::SIGN),
new \pocketmine\nbt\tag\Int("x", $chunkX * 16 + $x),
new \pocketmine\nbt\tag\Int("y", $y),
new \pocketmine\nbt\tag\Int("z", $chunkZ * 16 + $z)
]);
new \pocketmine\tile\Sign($chunk, $nbt);
$save = true;
}
}
}
}
}
if($save){
$world->setChunk($chunkX, $chunkZ, $chunk, false);
$world->saveChunks();
}
}
$world->unloadChunk($chunkX, $chunkZ, false);
++$count;
}
echo "[".round(($count/$total) * 100, 0)."%] $count/$total\n";
}
$world->save(true);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.