From 2330f363bd15a2c953fd538a807aba819405204f Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sun, 27 Jul 2014 20:54:28 +0200 Subject: [PATCH] Fix for thrown EmptyChunkSection modification exception --- src/pocketmine/level/format/LevelProvider.php | 7 ++++ src/pocketmine/level/format/anvil/Anvil.php | 10 ++++++ .../level/format/generic/BaseChunk.php | 35 ++++++++++++++++--- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/level/format/LevelProvider.php b/src/pocketmine/level/format/LevelProvider.php index fae814185..ea7b70f62 100644 --- a/src/pocketmine/level/format/LevelProvider.php +++ b/src/pocketmine/level/format/LevelProvider.php @@ -80,6 +80,13 @@ interface LevelProvider{ */ public function getChunk($X, $Z, $create = false); + /** + * @param $Y 0-7 + * + * @return ChunkSection + */ + public function createChunkSection($Y); + public function saveChunks(); /** diff --git a/src/pocketmine/level/format/anvil/Anvil.php b/src/pocketmine/level/format/anvil/Anvil.php index 9754d2a38..60dbe8ad6 100644 --- a/src/pocketmine/level/format/anvil/Anvil.php +++ b/src/pocketmine/level/format/anvil/Anvil.php @@ -223,6 +223,16 @@ class Anvil extends BaseLevelProvider{ } } + public function createChunkSection($Y){ + return new ChunkSection(new Compound(null, [ + "Y" => new Byte("Y", $Y), + "Blocks" => new ByteArray("Blocks", str_repeat("\xff", 4096)), + "Data" => new ByteArray("Data", str_repeat("\xff", 2048)), + "SkyLight" => new ByteArray("SkyLight", str_repeat("\xff", 2048)), //TODO + "BlockLight" => new ByteArray("BlockLight", str_repeat("\x00", 2048)) //TODO + ])); + } + public function isChunkGenerated($chunkX, $chunkZ){ if(($region = $this->getRegion($chunkX >> 5, $chunkZ >> 5)) instanceof RegionLoader){ return $region->chunkExists($chunkX - $region->getX() * 32, $chunkZ - $region->getZ() * 32); diff --git a/src/pocketmine/level/format/generic/BaseChunk.php b/src/pocketmine/level/format/generic/BaseChunk.php index ef1394465..561eb1c79 100644 --- a/src/pocketmine/level/format/generic/BaseChunk.php +++ b/src/pocketmine/level/format/generic/BaseChunk.php @@ -160,7 +160,12 @@ abstract class BaseChunk implements Chunk{ } public function setBlock($x, $y, $z, $blockId = null, $meta = null){ - return $this->sections[$y >> 4]->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f); + try{ + return $this->sections[$y >> 4]->setBlock($x, $y & 0x0f, $z, $blockId & 0xff, $meta & 0x0f); + }catch(\Exception $e){ + $this->setSection($Y = $y >> 4, $this->getLevel()->createChunkSection($Y)); + return $this->setBlock($x, $y, $z, $blockId, $meta); + } } public function getBlockId($x, $y, $z){ @@ -168,7 +173,12 @@ abstract class BaseChunk implements Chunk{ } public function setBlockId($x, $y, $z, $id){ - $this->sections[$y >> 4]->setBlockId($x, $y & 0x0f, $z, $id); + try{ + $this->sections[$y >> 4]->setBlockId($x, $y & 0x0f, $z, $id); + }catch(\Exception $e){ + $this->setSection($Y = $y >> 4, $this->getLevel()->createChunkSection($Y)); + $this->setBlockId($x, $y, $z, $id); + } } public function getBlockData($x, $y, $z){ @@ -176,7 +186,12 @@ abstract class BaseChunk implements Chunk{ } public function setBlockData($x, $y, $z, $data){ - $this->sections[$y >> 4]->setBlockData($x, $y & 0x0f, $z, $data); + try{ + $this->sections[$y >> 4]->setBlockData($x, $y & 0x0f, $z, $data); + }catch(\Exception $e){ + $this->setSection($Y = $y >> 4, $this->getLevel()->createChunkSection($Y)); + $this->setBlockData($x, $y, $z, $data); + } } public function getBlockSkyLight($x, $y, $z){ @@ -184,7 +199,12 @@ abstract class BaseChunk implements Chunk{ } public function setBlockSkyLight($x, $y, $z, $data){ - $this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data); + try{ + $this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data); + }catch(\Exception $e){ + $this->setSection($Y = $y >> 4, $this->getLevel()->createChunkSection($Y)); + $this->setBlockSkyLight($x, $y, $z, $data); + } } public function getBlockLight($x, $y, $z){ @@ -192,7 +212,12 @@ abstract class BaseChunk implements Chunk{ } public function setBlockLight($x, $y, $z, $data){ - $this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data); + try{ + $this->sections[$y >> 4]->getBlockSkyLight($x, $y & 0x0f, $z, $data); + }catch(\Exception $e){ + $this->setSection($Y = $y >> 4, $this->getLevel()->createChunkSection($Y)); + $this->setBlockLight($x, $y, $z, $data); + } } public function getBiomeId($x, $z){