From 3bb2f12cde2baacef2a76bc695270a56321e5bae Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Mon, 8 Dec 2014 20:54:47 +0100 Subject: [PATCH] Improved block reading * Created global block states array * Improved Level->getBlock() using block states * Improved Level->getBlock() for 64-bit systems * Added Level->getFullBlock() * Added FullChunk->getFullBlock() * Added Chunk->getFullBlock() * Added ChunkSection->getFullBlock() * Deprecated FullChunk->getBlock() * Deprecated Chunk->getBlock() * Deprecated ChunkSection->getBlock() --- src/pocketmine/block/Block.php | 15 ++++++++ src/pocketmine/inventory/PlayerInventory.php | 2 +- src/pocketmine/level/Level.php | 35 +++++++++++-------- src/pocketmine/level/format/ChunkSection.php | 13 +++++++ src/pocketmine/level/format/FullChunk.php | 13 +++++++ .../level/format/anvil/ChunkSection.php | 12 ++++--- .../level/format/generic/BaseChunk.php | 8 ++++- .../level/format/mcregion/Chunk.php | 14 +++++--- src/pocketmine/plugin/PluginDescription.php | 2 -- 9 files changed, 87 insertions(+), 27 deletions(-) diff --git a/src/pocketmine/block/Block.php b/src/pocketmine/block/Block.php index b78a38b87..7de20f408 100644 --- a/src/pocketmine/block/Block.php +++ b/src/pocketmine/block/Block.php @@ -528,6 +528,9 @@ class Block extends Position implements Metadatable{ /** @var \SplFixedArray */ public static $list = null; + /** @var \SplFixedArray */ + public static $fullList = null; + /** @var \SplFixedArray */ public static $light = null; /** @var \SplFixedArray */ @@ -572,6 +575,7 @@ class Block extends Position implements Metadatable{ public static function init(){ if(self::$list === null){ self::$list = new \SplFixedArray(256); + self::$fullList = new \SplFixedArray(4096); self::$light = new \SplFixedArray(256); self::$lightFilter = new \SplFixedArray(256); self::$solid = new \SplFixedArray(256); @@ -728,6 +732,11 @@ class Block extends Position implements Metadatable{ if($class !== null){ /** @var Block $block */ $block = new $class(); + + for($data = 0; $data < 16; ++$data){ + self::$fullList[($id << 4) | $data] = new $class($data); + } + self::$solid[$id] = $block->isSolid(); self::$transparent[$id] = $block->isTransparent(); self::$light[$id] = $block->getLightLevel(); @@ -749,6 +758,12 @@ class Block extends Position implements Metadatable{ self::$lightFilter[$id] = 1; } } + + foreach(self::$fullList as $id => $block){ + if($block === null){ + self::$fullList[$id] = new Block($id >> 4, $id & 0x0f); + } + } } } diff --git a/src/pocketmine/inventory/PlayerInventory.php b/src/pocketmine/inventory/PlayerInventory.php index 9613e12fc..83cc156ec 100644 --- a/src/pocketmine/inventory/PlayerInventory.php +++ b/src/pocketmine/inventory/PlayerInventory.php @@ -467,7 +467,7 @@ class PlayerInventory extends BaseInventory{ } /** - * @return Human + * @return Human|Player */ public function getHolder(){ return parent::getHolder(); diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index c2ad562ca..f2fb56616 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -895,6 +895,17 @@ class Level implements ChunkManager, Metadatable{ return $level; } + /** + * @param $x + * @param $y + * @param $z + * + * @return int bitmap, (id << 4) | data + */ + public function getFullBlock($x, $y, $z){ + return $this->getChunk($x >> 4, $z >> 4, false)->getFullBlock($x & 0x0f, $y & 0x7f, $z & 0x0f); + } + /** * Gets the Block object on the Vector3 location * @@ -904,25 +915,21 @@ class Level implements ChunkManager, Metadatable{ * @return Block */ public function getBlock(Vector3 $pos, $cached = true){ - $blockId = 0; - $meta = 0; - $index = "{$pos->x}:{$pos->y}:{$pos->z}"; + $fullState = 0; + $index = PHP_INT_SIZE === 8 ? (($pos->x & 0xFFFFFFF) << 35) | (($pos->y & 0x7f) << 28) | ($pos->z & 0xFFFFFFF) : "{$pos->x}:{$pos->y}:{$pos->z}"; if($cached and isset($this->blockCache[$index])){ return $this->blockCache[$index]; - }elseif($pos->y >= 0 and $pos->y < 128 and ($chunk = $this->getChunk($pos->x >> 4, $pos->z >> 4, true)) !== null){ - $chunk->getBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f, $blockId, $meta); + }elseif($pos->y >= 0 and $pos->y < 128 and ($chunk = $this->getChunk($pos->x >> 4, $pos->z >> 4, false)) !== null){ + $fullState = $chunk->getFullBlock($pos->x & 0x0f, $pos->y, $pos->z & 0x0f); } - if($blockId === 0){ - $air = new Air(); - $air->x = $pos->x; - $air->y = $pos->y; - $air->z = $pos->z; - $air->level = $this; - return $this->blockCache[$index] = $air; - } + $block = clone Block::$fullList[$fullState]; + $block->x = $pos->x; + $block->y = $pos->y; + $block->z = $pos->z; + $block->level = $this; - return $this->blockCache[$index] = Block::get($blockId, $meta, $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z)); + return $this->blockCache[$index] = $block; } public function updateAllLight(Vector3 $pos){ diff --git a/src/pocketmine/level/format/ChunkSection.php b/src/pocketmine/level/format/ChunkSection.php index 45d11dfe3..9de459921 100644 --- a/src/pocketmine/level/format/ChunkSection.php +++ b/src/pocketmine/level/format/ChunkSection.php @@ -65,6 +65,8 @@ interface ChunkSection{ /** * Modifies $blockId and $meta * + * @deprecated + * * @param int $x 0-15 * @param int $y 0-15 * @param int $z 0-15 @@ -73,6 +75,17 @@ interface ChunkSection{ */ public function getBlock($x, $y, $z, &$blockId, &$meta = null); + /** + * Gets block and meta in one go + * + * @param int $x 0-15 + * @param int $y 0-15 + * @param int $z 0-15 + * + * @return int bitmap, (id << 4) | data + */ + public function getFullBlock($x, $y, $z); + /** * @param int $x 0-15 * @param int $y 0-15 diff --git a/src/pocketmine/level/format/FullChunk.php b/src/pocketmine/level/format/FullChunk.php index 73478094b..b40fcedc7 100644 --- a/src/pocketmine/level/format/FullChunk.php +++ b/src/pocketmine/level/format/FullChunk.php @@ -54,6 +54,8 @@ interface FullChunk{ /** * Modifies $blockId and $meta * + * @deprecated + * * @param int $x 0-15 * @param int $y 0-127 * @param int $z 0-15 @@ -62,6 +64,17 @@ interface FullChunk{ */ public function getBlock($x, $y, $z, &$blockId, &$meta = null); + /** + * Gets block and meta in one go + * + * @param int $x 0-15 + * @param int $y 0-15 + * @param int $z 0-15 + * + * @return int bitmap, (id << 4) | data + */ + public function getFullBlock($x, $y, $z); + /** * @param int $x 0-15 * @param int $y 0-127 diff --git a/src/pocketmine/level/format/anvil/ChunkSection.php b/src/pocketmine/level/format/anvil/ChunkSection.php index 22c897a75..bb42a551d 100644 --- a/src/pocketmine/level/format/anvil/ChunkSection.php +++ b/src/pocketmine/level/format/anvil/ChunkSection.php @@ -71,13 +71,17 @@ class ChunkSection implements \pocketmine\level\format\ChunkSection{ } public function getBlock($x, $y, $z, &$blockId, &$meta = null){ + $full = $this->getFullBlock($x, $y, $z); + $blockId = $full >> 4; + $meta = $full & 0x0f; + } + + public function getFullBlock($x, $y, $z){ $i = ($y << 8) + ($z << 4) + $x; - $blockId = ord($this->blocks{$i}); - $m = ord($this->data{$i >> 1}); if(($x & 1) === 0){ - $meta = $m & 0x0F; + return (ord($this->blocks{$i}) << 4) | (ord($this->data{$i >> 1}) & 0x0F); }else{ - $meta = $m >> 4; + return (ord($this->blocks{$i}) << 4) | (ord($this->data{$i >> 1}) >> 4); } } diff --git a/src/pocketmine/level/format/generic/BaseChunk.php b/src/pocketmine/level/format/generic/BaseChunk.php index 35b5a51c6..7d2363885 100644 --- a/src/pocketmine/level/format/generic/BaseChunk.php +++ b/src/pocketmine/level/format/generic/BaseChunk.php @@ -87,7 +87,13 @@ abstract class BaseChunk extends BaseFullChunk implements Chunk{ } public function getBlock($x, $y, $z, &$blockId, &$meta = null){ - $this->sections[$y >> 4]->getBlock($x, $y & 0x0f, $z, $blockId, $meta); + $full = $this->sections[$y >> 4]->getFullBlock($x, $y & 0x0f, $z); + $blockId = $full >> 4; + $meta = $full & 0x0f; + } + + public function getFullBlock($x, $y, $z){ + return $this->sections[$y >> 4]->getFullBlock($x, $y & 0x0f, $z); } public function setBlock($x, $y, $z, $blockId = null, $meta = null){ diff --git a/src/pocketmine/level/format/mcregion/Chunk.php b/src/pocketmine/level/format/mcregion/Chunk.php index 3a591da4c..09d19b68e 100644 --- a/src/pocketmine/level/format/mcregion/Chunk.php +++ b/src/pocketmine/level/format/mcregion/Chunk.php @@ -120,17 +120,21 @@ class Chunk extends BaseFullChunk{ $this->hasChanged = true; } - public function getBlock($x, $y, $z, &$blockId, &$meta = null){ + public function getFullBlock($x, $y, $z){ $i = ($x << 11) + ($z << 7) + $y; - $blockId = ord($this->blocks{$i}); - $m = ord($this->data{$i >> 1}); if(($y & 1) === 0){ - $meta = $m & 0x0F; + return (ord($this->blocks{$i}) << 4) | (ord($this->data{$i >> 1}) & 0x0F); }else{ - $meta = $m >> 4; + return (ord($this->blocks{$i}) << 4) | (ord($this->data{$i >> 1}) >> 4); } } + public function getBlock($x, $y, $z, &$blockId, &$meta = null){ + $full = $this->getFullBlock($x, $y, $z); + $blockId = $full >> 4; + $meta = $full & 0x0f; + } + public function setBlock($x, $y, $z, $blockId = null, $meta = null){ $i = ($x << 11) + ($z << 7) + $y; diff --git a/src/pocketmine/plugin/PluginDescription.php b/src/pocketmine/plugin/PluginDescription.php index 74afaddd5..738669b5e 100644 --- a/src/pocketmine/plugin/PluginDescription.php +++ b/src/pocketmine/plugin/PluginDescription.php @@ -67,8 +67,6 @@ class PluginDescription{ $this->api = !is_array($plugin["api"]) ? [$plugin["api"]] : $plugin["api"]; if(stripos($this->main, "pocketmine\\") === 0){ throw new PluginException("Invalid PluginDescription main, cannot start within the PocketMine namespace"); - - return; } if(isset($plugin["commands"]) and is_array($plugin["commands"])){